diff --git a/.gitattributes b/.gitattributes index 23c253a26d08a..8dd4fe466ad6e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,5 +3,8 @@ crates/ruff_linter/resources/test/fixtures/isort/line_ending_crlf.py text eol=crlf crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py text eol=crlf +crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py text eol=crlf +crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap text eol=crlf + ruff.schema.json linguist-generated=true text=auto eol=lf *.md.snap linguist-language=Markdown diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 07281de43f486..f4649c34617f0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,8 +23,13 @@ jobs: name: "Determine changes" runs-on: ubuntu-latest outputs: + # Flag that is raised when any code that affects linter is changed linter: ${{ steps.changed.outputs.linter_any_changed }} + # Flag that is raised when any code that affects formatter is changed formatter: ${{ steps.changed.outputs.formatter_any_changed }} + # Flag that is raised when any code is changed + # This is superset of the linter and formatter + code: ${{ steps.changed.outputs.code_any_changed }} steps: - uses: actions/checkout@v4 with: @@ -43,6 +48,7 @@ jobs: - "!crates/ruff_dev/**" - "!crates/ruff_shrinking/**" - scripts/* + - python/** - .github/workflows/ci.yaml formatter: @@ -58,8 +64,15 @@ jobs: - crates/ruff_python_parser/** - crates/ruff_dev/** - scripts/* + - python/** - .github/workflows/ci.yaml + code: + - "**/*" + - "!**/*.md" + - "!docs/**" + - "!assets/**" + cargo-fmt: name: "cargo fmt" runs-on: ubuntu-latest @@ -72,6 +85,8 @@ jobs: cargo-clippy: name: "cargo clippy" runs-on: ubuntu-latest + needs: determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 - name: "Install Rust toolchain" @@ -86,6 +101,8 @@ jobs: cargo-test-linux: runs-on: ubuntu-latest + needs: determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} name: "cargo test (linux)" steps: - uses: actions/checkout@v4 @@ -110,6 +127,8 @@ jobs: cargo-test-windows: runs-on: windows-latest + needs: determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} name: "cargo test (windows)" steps: - uses: actions/checkout@v4 @@ -127,6 +146,8 @@ jobs: cargo-test-wasm: runs-on: ubuntu-latest + needs: determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} name: "cargo test (wasm)" steps: - uses: actions/checkout@v4 @@ -146,6 +167,8 @@ jobs: cargo-fuzz: runs-on: ubuntu-latest + needs: determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} name: "cargo fuzz" steps: - uses: actions/checkout@v4 @@ -163,6 +186,8 @@ jobs: scripts: name: "test scripts" runs-on: ubuntu-latest + needs: determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 - name: "Install Rust toolchain" @@ -186,12 +211,11 @@ jobs: # Only runs on pull requests, since that is the only we way we can find the base version for comparison. # Ecosystem check needs linter and/or formatter changes. if: github.event_name == 'pull_request' && ${{ - needs.determine_changes.outputs.linter == 'true' || - needs.determine_changes.outputs.formatter == 'true' + needs.determine_changes.outputs.code == 'true' }} steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} @@ -296,6 +320,8 @@ jobs: cargo-udeps: name: "cargo udeps" runs-on: ubuntu-latest + needs: determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 - name: "Install nightly Rust toolchain" @@ -312,7 +338,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -336,7 +362,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: "Install Rust toolchain" @@ -366,7 +392,7 @@ jobs: MKDOCS_INSIDERS_SSH_KEY_EXISTS: ${{ secrets.MKDOCS_INSIDERS_SSH_KEY != '' }} steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 - name: "Add SSH key" if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }} uses: webfactory/ssh-agent@v0.8.0 @@ -415,7 +441,10 @@ jobs: check-ruff-lsp: name: "test ruff-lsp" runs-on: ubuntu-latest - needs: cargo-test-linux + needs: + - cargo-test-linux + - determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} steps: - uses: extractions/setup-just@v1 env: @@ -426,7 +455,7 @@ jobs: with: repository: "astral-sh/ruff-lsp" - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} @@ -453,6 +482,8 @@ jobs: benchmarks: runs-on: ubuntu-latest + needs: determine_changes + if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} steps: - name: "Checkout Branch" uses: actions/checkout@v4 @@ -471,7 +502,7 @@ jobs: run: cargo codspeed build --features codspeed -p ruff_benchmark - name: "Run benchmarks" - uses: CodSpeedHQ/action@v1 + uses: CodSpeedHQ/action@v2 with: run: cargo codspeed run token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 992ca27a9389f..13bf7a87598c9 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.ref }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 - name: "Add SSH key" if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }} uses: webfactory/ssh-agent@v0.8.0 diff --git a/.github/workflows/flake8-to-ruff.yaml b/.github/workflows/flake8-to-ruff.yaml index feb1c2825aa9d..ebc38cb4fea56 100644 --- a/.github/workflows/flake8-to-ruff.yaml +++ b/.github/workflows/flake8-to-ruff.yaml @@ -20,7 +20,7 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -43,7 +43,7 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -69,7 +69,7 @@ jobs: target: [x64, x86] steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: ${{ matrix.target }} @@ -97,7 +97,7 @@ jobs: target: [x86_64, i686] steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -124,7 +124,7 @@ jobs: target: [aarch64, armv7, s390x, ppc64le, ppc64] steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: "Build wheels" @@ -161,7 +161,7 @@ jobs: - i686-unknown-linux-musl steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -197,7 +197,7 @@ jobs: arch: armv7 steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: "Build wheels" @@ -237,7 +237,7 @@ jobs: - uses: actions/download-artifact@v3 with: name: wheels - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 - name: "Publish to PyPi" env: TWINE_USERNAME: __token__ diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a958e80a8b67c..368bd3bff0641 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.sha }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: "Prep README.md" @@ -63,7 +63,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.sha }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -86,7 +86,7 @@ jobs: path: dist - name: "Archive binary" run: | - ARCHIVE_FILE=ruff-x86_64-apple-darwin.tar.gz + ARCHIVE_FILE=ruff-${{ inputs.tag }}-x86_64-apple-darwin.tar.gz tar czvf $ARCHIVE_FILE -C target/x86_64-apple-darwin/release ruff shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256 - name: "Upload binary" @@ -103,7 +103,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.sha }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -125,7 +125,7 @@ jobs: path: dist - name: "Archive binary" run: | - ARCHIVE_FILE=ruff-aarch64-apple-darwin.tar.gz + ARCHIVE_FILE=ruff-${{ inputs.tag }}-aarch64-apple-darwin.tar.gz tar czvf $ARCHIVE_FILE -C target/aarch64-apple-darwin/release ruff shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256 - name: "Upload binary" @@ -151,7 +151,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.sha }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: ${{ matrix.platform.arch }} @@ -177,7 +177,7 @@ jobs: - name: "Archive binary" shell: bash run: | - ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.zip + ARCHIVE_FILE=ruff-${{ inputs.tag }}-${{ matrix.platform.target }}.zip 7z a $ARCHIVE_FILE ./target/${{ matrix.platform.target }}/release/ruff.exe sha256sum $ARCHIVE_FILE > $ARCHIVE_FILE.sha256 - name: "Upload binary" @@ -199,7 +199,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.sha }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -224,7 +224,7 @@ jobs: path: dist - name: "Archive binary" run: | - ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz + ARCHIVE_FILE=ruff-${{ inputs.tag }}-${{ matrix.target }}.tar.gz tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256 - name: "Upload binary" @@ -258,7 +258,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.sha }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: "Prep README.md" @@ -291,7 +291,7 @@ jobs: path: dist - name: "Archive binary" run: | - ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz + ARCHIVE_FILE=ruff-${{ inputs.tag }}-${{ matrix.platform.target }}.tar.gz tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256 - name: "Upload binary" @@ -313,7 +313,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.sha }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} architecture: x64 @@ -332,10 +332,10 @@ jobs: image: alpine:latest options: -v ${{ github.workspace }}:/io -w /io run: | - apk add py3-pip - pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links /io/dist/ --force-reinstall - ruff --help - python -m ruff --help + apk add python3 + python -m venv .venv + .venv/bin/pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall + .venv/bin/ruff check --help - name: "Upload wheels" uses: actions/upload-artifact@v3 with: @@ -343,7 +343,7 @@ jobs: path: dist - name: "Archive binary" run: | - ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz + ARCHIVE_FILE=ruff-${{ inputs.tag }}-${{ matrix.target }}.tar.gz tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256 - name: "Upload binary" @@ -369,7 +369,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.sha }} - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: "Prep README.md" @@ -388,10 +388,11 @@ jobs: distro: alpine_latest githubToken: ${{ github.token }} install: | - apk add py3-pip + apk add python3 run: | - pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall - ruff check --help + python -m venv .venv + .venv/bin/pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall + .venv/bin/ruff check --help - name: "Upload wheels" uses: actions/upload-artifact@v3 with: @@ -399,7 +400,7 @@ jobs: path: dist - name: "Archive binary" run: | - ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz + ARCHIVE_FILE=ruff-${{ inputs.tag }}-${{ matrix.platform.target }}.tar.gz tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256 - name: "Upload binary" @@ -541,7 +542,7 @@ jobs: - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: ghcr.io/astral-sh/ruff @@ -561,7 +562,7 @@ jobs: fi - name: "Build and push Docker image" - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 @@ -580,7 +581,7 @@ jobs: needs: publish-release steps: - name: "Update pre-commit mirror" - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{ secrets.RUFF_PRE_COMMIT_PAT }} script: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 766439b59e989..cebb80b27088e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,156 @@ # Changelog +## 0.1.8 + +This release includes opt-in support for formatting Python snippets within +docstrings via the `docstring-code-format` setting. +[Check out the blog post](https://astral.sh/blog/ruff-v0.1.8) for more details! + +### Preview features + +- Add `"preserve"` quote-style to mimic Black's skip-string-normalization ([#8822](https://github.com/astral-sh/ruff/pull/8822)) +- Implement `prefer_splitting_right_hand_side_of_assignments` preview style ([#8943](https://github.com/astral-sh/ruff/pull/8943)) +- \[`pycodestyle`\] Add fix for `unexpected-spaces-around-keyword-parameter-equals` ([#9072](https://github.com/astral-sh/ruff/pull/9072)) +- \[`pycodestyle`\] Add fix for comment-related whitespace rules ([#9075](https://github.com/astral-sh/ruff/pull/9075)) +- \[`pycodestyle`\] Allow `sys.path` modifications between imports ([#9047](https://github.com/astral-sh/ruff/pull/9047)) +- \[`refurb`\] Implement `hashlib-digest-hex` (`FURB181`) ([#9077](https://github.com/astral-sh/ruff/pull/9077)) + +### Rule changes + +- Allow `flake8-type-checking` rules to automatically quote runtime-evaluated references ([#6001](https://github.com/astral-sh/ruff/pull/6001)) +- Allow transparent cell magics in Jupyter Notebooks ([#8911](https://github.com/astral-sh/ruff/pull/8911)) +- \[`flake8-annotations`\] Avoid `ANN2xx` fixes for abstract methods with empty bodies ([#9034](https://github.com/astral-sh/ruff/pull/9034)) +- \[`flake8-self`\] Ignore underscore references in type annotations ([#9036](https://github.com/astral-sh/ruff/pull/9036)) +- \[`pep8-naming`\] Allow class names when `apps.get_model` is a non-string ([#9065](https://github.com/astral-sh/ruff/pull/9065)) +- \[`pycodestyle`\] Allow `matplotlib.use` calls to intersperse imports ([#9094](https://github.com/astral-sh/ruff/pull/9094)) +- \[`pyflakes`\] Support fixing unused assignments in tuples by renaming variables (`F841`) ([#9107](https://github.com/astral-sh/ruff/pull/9107)) +- \[`pylint`\] Add fix for `subprocess-run-without-check` (`PLW1510`) ([#6708](https://github.com/astral-sh/ruff/pull/6708)) + +### Formatter + +- Add `docstring-code-format` knob to enable docstring snippet formatting ([#8854](https://github.com/astral-sh/ruff/pull/8854)) +- Use double quotes for all docstrings, including single-quoted docstrings ([#9020](https://github.com/astral-sh/ruff/pull/9020)) +- Implement "dynamic" line width mode for docstring code formatting ([#9098](https://github.com/astral-sh/ruff/pull/9098)) +- Support reformatting Markdown code blocks ([#9030](https://github.com/astral-sh/ruff/pull/9030)) +- add support for formatting reStructuredText code snippets ([#9003](https://github.com/astral-sh/ruff/pull/9003)) +- Avoid trailing comma for single-argument with positional separator ([#9076](https://github.com/astral-sh/ruff/pull/9076)) +- Fix handling of trailing target comment ([#9051](https://github.com/astral-sh/ruff/pull/9051)) + +### CLI + +- Hide unsafe fix suggestions when explicitly disabled ([#9095](https://github.com/astral-sh/ruff/pull/9095)) +- Add SARIF support to `--output-format` ([#9078](https://github.com/astral-sh/ruff/pull/9078)) + +### Bug fixes + +- Apply unnecessary index rule prior to enumerate rewrite ([#9012](https://github.com/astral-sh/ruff/pull/9012)) +- \[`flake8-err-msg`\] Allow `EM` fixes even if `msg` variable is defined ([#9059](https://github.com/astral-sh/ruff/pull/9059)) +- \[`flake8-pie`\] Prevent keyword arguments duplication ([#8450](https://github.com/astral-sh/ruff/pull/8450)) +- \[`flake8-pie`\] Respect trailing comma in `unnecessary-dict-kwargs` (`PIE804`) ([#9015](https://github.com/astral-sh/ruff/pull/9015)) +- \[`flake8-raise`\] Avoid removing parentheses on ctypes.WinError ([#9027](https://github.com/astral-sh/ruff/pull/9027)) +- \[`isort`\] Avoid invalid combination of `force-sort-within-types` and `lines-between-types` ([#9041](https://github.com/astral-sh/ruff/pull/9041)) +- \[`isort`\] Ensure that from-style imports are always ordered first in `__future__` ([#9039](https://github.com/astral-sh/ruff/pull/9039)) +- \[`pycodestyle`\] Allow tab indentation before keyword ([#9099](https://github.com/astral-sh/ruff/pull/9099)) +- \[`pylint`\] Ignore `@overrides` and `@overloads` for `too-many-positional` ([#9000](https://github.com/astral-sh/ruff/pull/9000)) +- \[`pyupgrade`\] Enable `printf-string-formatting` fix with comments on right-hand side ([#9037](https://github.com/astral-sh/ruff/pull/9037)) +- \[`refurb`\] Make `math-constant` (`FURB152`) rule more targeted ([#9054](https://github.com/astral-sh/ruff/pull/9054)) +- \[`refurb`\] Support floating-point base in `redundant-log-base` (`FURB163`) ([#9100](https://github.com/astral-sh/ruff/pull/9100)) +- \[`ruff`\] Detect `unused-asyncio-dangling-task` (`RUF006`) on unused assignments ([#9060](https://github.com/astral-sh/ruff/pull/9060)) + +## 0.1.7 + +### Preview features + +- Implement multiline dictionary and list hugging for preview style ([#8293](https://github.com/astral-sh/ruff/pull/8293)) +- Implement the `fix_power_op_line_length` preview style ([#8947](https://github.com/astral-sh/ruff/pull/8947)) +- Use Python version to determine typing rewrite safety ([#8919](https://github.com/astral-sh/ruff/pull/8919)) +- \[`flake8-annotations`\] Enable auto-return-type involving `Optional` and `Union` annotations ([#8885](https://github.com/astral-sh/ruff/pull/8885)) +- \[`flake8-bandit`\] Implement `django-raw-sql` (`S611`) ([#8651](https://github.com/astral-sh/ruff/pull/8651)) +- \[`flake8-bandit`\] Implement `tarfile-unsafe-members` (`S202`) ([#8829](https://github.com/astral-sh/ruff/pull/8829)) +- \[`flake8-pyi`\] Implement fix for `unnecessary-literal-union` (`PYI030`) ([#7934](https://github.com/astral-sh/ruff/pull/7934)) +- \[`flake8-simplify`\] Extend `dict-get-with-none-default` (`SIM910`) to non-literals ([#8762](https://github.com/astral-sh/ruff/pull/8762)) +- \[`pylint`\] - add `unnecessary-list-index-lookup` (`PLR1736`) + autofix ([#7999](https://github.com/astral-sh/ruff/pull/7999)) +- \[`pylint`\] - implement R0202 and R0203 with autofixes ([#8335](https://github.com/astral-sh/ruff/pull/8335)) +- \[`pylint`\] Implement `repeated-keyword` (`PLe1132`) ([#8706](https://github.com/astral-sh/ruff/pull/8706)) +- \[`pylint`\] Implement `too-many-positional` (`PLR0917`) ([#8995](https://github.com/astral-sh/ruff/pull/8995)) +- \[`pylint`\] Implement `unnecessary-dict-index-lookup` (`PLR1733`) ([#8036](https://github.com/astral-sh/ruff/pull/8036)) +- \[`refurb`\] Implement `redundant-log-base` (`FURB163`) ([#8842](https://github.com/astral-sh/ruff/pull/8842)) + +### Rule changes + +- \[`flake8-boolean-trap`\] Allow booleans in `@override` methods ([#8882](https://github.com/astral-sh/ruff/pull/8882)) +- \[`flake8-bugbear`\] Avoid `B015`,`B018` for last expression in a cell ([#8815](https://github.com/astral-sh/ruff/pull/8815)) +- \[`flake8-pie`\] Allow ellipses for enum values in stub files ([#8825](https://github.com/astral-sh/ruff/pull/8825)) +- \[`flake8-pyi`\] Check PEP 695 type aliases for `snake-case-type-alias` and `t-suffixed-type-alias` ([#8966](https://github.com/astral-sh/ruff/pull/8966)) +- \[`flake8-pyi`\] Check for kwarg and vararg `NoReturn` type annotations ([#8948](https://github.com/astral-sh/ruff/pull/8948)) +- \[`flake8-simplify`\] Omit select context managers from `SIM117` ([#8801](https://github.com/astral-sh/ruff/pull/8801)) +- \[`pep8-naming`\] Allow Django model loads in `non-lowercase-variable-in-function` (`N806`) ([#8917](https://github.com/astral-sh/ruff/pull/8917)) +- \[`pycodestyle`\] Avoid `E703` for last expression in a cell ([#8821](https://github.com/astral-sh/ruff/pull/8821)) +- \[`pycodestyle`\] Update `E402` to work at cell level for notebooks ([#8872](https://github.com/astral-sh/ruff/pull/8872)) +- \[`pydocstyle`\] Avoid `D100` for Jupyter Notebooks ([#8816](https://github.com/astral-sh/ruff/pull/8816)) +- \[`pylint`\] Implement fix for `unspecified-encoding` (`PLW1514`) ([#8928](https://github.com/astral-sh/ruff/pull/8928)) + +### Formatter + +- Avoid unstable formatting in ellipsis-only body with trailing comment ([#8984](https://github.com/astral-sh/ruff/pull/8984)) +- Inline trailing comments for type alias similar to assignments ([#8941](https://github.com/astral-sh/ruff/pull/8941)) +- Insert trailing comma when function breaks with single argument ([#8921](https://github.com/astral-sh/ruff/pull/8921)) + +### CLI + +- Update `ruff check` and `ruff format` to default to the current directory ([#8791](https://github.com/astral-sh/ruff/pull/8791)) +- Stop at the first resolved parent configuration ([#8864](https://github.com/astral-sh/ruff/pull/8864)) + +### Configuration + +- \[`pylint`\] Default `max-positional-args` to `max-args` ([#8998](https://github.com/astral-sh/ruff/pull/8998)) +- \[`pylint`\] Add `allow-dunder-method-names` setting for `bad-dunder-method-name` (`PLW3201`) ([#8812](https://github.com/astral-sh/ruff/pull/8812)) +- \[`isort`\] Add support for `from-first` setting ([#8663](https://github.com/astral-sh/ruff/pull/8663)) +- \[`isort`\] Add support for `length-sort` settings ([#8841](https://github.com/astral-sh/ruff/pull/8841)) + +### Bug fixes + +- Add support for `@functools.singledispatch` ([#8934](https://github.com/astral-sh/ruff/pull/8934)) +- Avoid off-by-one error in stripping noqa following multi-byte char ([#8979](https://github.com/astral-sh/ruff/pull/8979)) +- Avoid off-by-one error in with-item named expressions ([#8915](https://github.com/astral-sh/ruff/pull/8915)) +- Avoid syntax error via invalid ur string prefix ([#8971](https://github.com/astral-sh/ruff/pull/8971)) +- Avoid underflow in `get_model` matching ([#8965](https://github.com/astral-sh/ruff/pull/8965)) +- Avoid unnecessary index diagnostics when value is modified ([#8970](https://github.com/astral-sh/ruff/pull/8970)) +- Convert over-indentation rule to use number of characters ([#8983](https://github.com/astral-sh/ruff/pull/8983)) +- Detect implicit returns in auto-return-types ([#8952](https://github.com/astral-sh/ruff/pull/8952)) +- Fix start >= end error in over-indentation ([#8982](https://github.com/astral-sh/ruff/pull/8982)) +- Ignore `@overload` and `@override` methods for too-many-arguments checks ([#8954](https://github.com/astral-sh/ruff/pull/8954)) +- Lexer start of line is false only for `Mode::Expression` ([#8880](https://github.com/astral-sh/ruff/pull/8880)) +- Mark `pydantic_settings.BaseSettings` as having default copy semantics ([#8793](https://github.com/astral-sh/ruff/pull/8793)) +- Respect dictionary unpacking in `NamedTuple` assignments ([#8810](https://github.com/astral-sh/ruff/pull/8810)) +- Respect local subclasses in `flake8-type-checking` ([#8768](https://github.com/astral-sh/ruff/pull/8768)) +- Support type alias statements in simple statement positions ([#8916](https://github.com/astral-sh/ruff/pull/8916)) +- \[`flake8-annotations`\] Avoid filtering out un-representable types in return annotation ([#8881](https://github.com/astral-sh/ruff/pull/8881)) +- \[`flake8-pie`\] Retain extra ellipses in protocols and abstract methods ([#8769](https://github.com/astral-sh/ruff/pull/8769)) +- \[`flake8-pyi`\] Respect local enum subclasses in `simple-defaults` (`PYI052`) ([#8767](https://github.com/astral-sh/ruff/pull/8767)) +- \[`flake8-trio`\] Use correct range for `TRIO115` fix ([#8933](https://github.com/astral-sh/ruff/pull/8933)) +- \[`flake8-trio`\] Use full arguments range for zero-sleep-call ([#8936](https://github.com/astral-sh/ruff/pull/8936)) +- \[`isort`\] fix: mark `__main__` as first-party import ([#8805](https://github.com/astral-sh/ruff/pull/8805)) +- \[`pep8-naming`\] Avoid `N806` errors for type alias statements ([#8785](https://github.com/astral-sh/ruff/pull/8785)) +- \[`perflint`\] Avoid `PERF101` if there's an append in loop body ([#8809](https://github.com/astral-sh/ruff/pull/8809)) +- \[`pycodestyle`\] Allow space-before-colon after end-of-slice ([#8838](https://github.com/astral-sh/ruff/pull/8838)) +- \[`pydocstyle`\] Avoid non-character breaks in `over-indentation` (`D208`) ([#8866](https://github.com/astral-sh/ruff/pull/8866)) +- \[`pydocstyle`\] Ignore underlines when determining docstring logical lines ([#8929](https://github.com/astral-sh/ruff/pull/8929)) +- \[`pylint`\] Extend `self-assigning-variable` to multi-target assignments ([#8839](https://github.com/astral-sh/ruff/pull/8839)) +- \[`tryceratops`\] Avoid repeated triggers in nested `tryceratops` diagnostics ([#8772](https://github.com/astral-sh/ruff/pull/8772)) + +### Documentation + +- Add advice for fixing RUF008 when mutability is not desired ([#8853](https://github.com/astral-sh/ruff/pull/8853)) +- Added the command to run ruff using pkgx to the installation.md ([#8955](https://github.com/astral-sh/ruff/pull/8955)) +- Document fix safety for flake8-comprehensions and some pyupgrade rules ([#8918](https://github.com/astral-sh/ruff/pull/8918)) +- Fix doc formatting for zero-sleep-call ([#8937](https://github.com/astral-sh/ruff/pull/8937)) +- Remove duplicate imports from os-stat documentation ([#8930](https://github.com/astral-sh/ruff/pull/8930)) +- Replace generated reference to MkDocs ([#8806](https://github.com/astral-sh/ruff/pull/8806)) +- Update Arch Linux package URL in installation.md ([#8802](https://github.com/astral-sh/ruff/pull/8802)) +- \[`flake8-pyi`\] Fix error in `t-suffixed-type-alias` (`PYI043`) example ([#8963](https://github.com/astral-sh/ruff/pull/8963)) +- \[`flake8-pyi`\] Improve motivation for `custom-type-var-return-type` (`PYI019`) ([#8766](https://github.com/astral-sh/ruff/pull/8766)) + ## 0.1.6 ### Preview features diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6f940ce73b91d..d79da233ebbab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -295,7 +295,7 @@ To preview any changes to the documentation locally: ```shell # For contributors. - mkdocs serve -f mkdocs.generated.yml + mkdocs serve -f mkdocs.public.yml # For members of the Astral org, which has access to MkDocs Insiders via sponsorship. mkdocs serve -f mkdocs.insiders.yml @@ -556,10 +556,10 @@ examples. #### Linux -Install `perf` and build `ruff_benchmark` with the `release-debug` profile and then run it with perf +Install `perf` and build `ruff_benchmark` with the `profiling` profile and then run it with perf ```shell -cargo bench -p ruff_benchmark --no-run --profile=release-debug && perf record --call-graph dwarf -F 9999 cargo bench -p ruff_benchmark --profile=release-debug -- --profile-time=1 +cargo bench -p ruff_benchmark --no-run --profile=profiling && perf record --call-graph dwarf -F 9999 cargo bench -p ruff_benchmark --profile=profiling -- --profile-time=1 ``` You can also use the `ruff_dev` launcher to run `ruff check` multiple times on a repository to @@ -567,8 +567,8 @@ gather enough samples for a good flamegraph (change the 999, the sample rate, an of checks, to your liking) ```shell -cargo build --bin ruff_dev --profile=release-debug -perf record -g -F 999 target/release-debug/ruff_dev repeat --repeat 30 --exit-zero --no-cache path/to/cpython > /dev/null +cargo build --bin ruff_dev --profile=profiling +perf record -g -F 999 target/profiling/ruff_dev repeat --repeat 30 --exit-zero --no-cache path/to/cpython > /dev/null ``` Then convert the recorded profile @@ -598,7 +598,7 @@ cargo install cargo-instruments Then run the profiler with ```shell -cargo instruments -t time --bench linter --profile release-debug -p ruff_benchmark -- --profile-time=1 +cargo instruments -t time --bench linter --profile profiling -p ruff_benchmark -- --profile-time=1 ``` - `-t`: Specifies what to profile. Useful options are `time` to profile the wall time and `alloc` diff --git a/Cargo.lock b/Cargo.lock index 18a152cbca0ee..c17db959ae1c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,14 +16,15 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -381,7 +382,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -405,9 +406,9 @@ dependencies = [ [[package]] name = "codspeed" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918b13a0f1a32460ab3bd5debd56b5a27a7071fa5ff5dfeb3a5cf291a85b174b" +checksum = "0eb4ab4dcb6554eb4f590fb16f99d3b102ab76f5f56554c9a5340518b32c499b" dependencies = [ "colored", "libc", @@ -416,9 +417,9 @@ dependencies = [ [[package]] name = "codspeed-criterion-compat" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c683c7fef2b873fbbdf4062782914c652309951244bf0bd362fe608b7d6f901c" +checksum = "cc07a3d3f7e0c8961d0ffdee149d39b231bafdcdc3d978dc5ad790c615f55f3f" dependencies = [ "codspeed", "colored", @@ -444,9 +445,9 @@ dependencies = [ [[package]] name = "configparser" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5458d9d1a587efaf5091602c59d299696a3877a439c8f6d461a2d3cce11df87a" +checksum = "e0e56e414a2a52ab2a104f85cd40933c2fbc278b83637facf646ecf451b49237" [[package]] name = "console" @@ -606,7 +607,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -617,7 +618,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -790,14 +791,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -808,7 +809,7 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flake8-to-ruff" -version = "0.1.6" +version = "0.1.8" dependencies = [ "anyhow", "clap", @@ -848,18 +849,18 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "fs-err" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5fd9bcbe8b1087cbd395b51498c01bc997cef73e778a80b77a811af5e2d29f" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" dependencies = [ "autocfg", ] @@ -903,15 +904,15 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", ] [[package]] @@ -987,9 +988,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1122,15 +1123,15 @@ dependencies = [ [[package]] name = "is-macro" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4467ed1321b310c2625c5aa6c1b1ffc5de4d9e42668cf697a08fb033ee8265e" +checksum = "bc74b7abae208af9314a406bd7dcc65091230b6e749c09e07a645885fecf34f9" dependencies = [ "Inflector", "pmutil 0.6.1", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -1170,9 +1171,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -1622,9 +1623,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" @@ -1708,7 +1709,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -1793,9 +1794,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -2062,7 +2063,7 @@ dependencies = [ [[package]] name = "ruff_cli" -version = "0.1.6" +version = "0.1.8" dependencies = [ "annotate-snippets 0.9.2", "anyhow", @@ -2198,7 +2199,7 @@ dependencies = [ [[package]] name = "ruff_linter" -version = "0.1.6" +version = "0.1.8" dependencies = [ "aho-corasick", "annotate-snippets 0.9.2", @@ -2258,6 +2259,7 @@ dependencies = [ "typed-arena", "unicode-width", "unicode_names2", + "url", "wsl", ] @@ -2269,7 +2271,7 @@ dependencies = [ "proc-macro2", "quote", "ruff_python_trivia", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -2334,6 +2336,7 @@ dependencies = [ "itertools 0.11.0", "memchr", "once_cell", + "regex", "ruff_cache", "ruff_formatter", "ruff_macros", @@ -2449,7 +2452,7 @@ dependencies = [ [[package]] name = "ruff_shrinking" -version = "0.1.6" +version = "0.1.8" dependencies = [ "anyhow", "clap", @@ -2617,9 +2620,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -2629,9 +2632,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -2675,18 +2678,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.190" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde-wasm-bindgen" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ba92964781421b6cef36bf0d7da26d201e96d84e1b10e7ae6ed416e516906d" +checksum = "b9b713f70513ae1f8d92665bbbbda5c295c2cf1da5542881ae5eefe20c9af132" dependencies = [ "js-sys", "serde", @@ -2695,13 +2698,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -2763,7 +2766,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -2867,7 +2870,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -2883,9 +2886,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" dependencies = [ "proc-macro2", "quote", @@ -2972,7 +2975,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -2984,7 +2987,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", "test-case-core", ] @@ -3005,7 +3008,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -3167,7 +3170,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -3194,20 +3197,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", @@ -3333,9 +3336,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "ureq" -version = "2.8.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" +checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" dependencies = [ "base64", "flate2", @@ -3349,9 +3352,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -3367,9 +3370,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "getrandom", "rand", @@ -3379,13 +3382,13 @@ dependencies = [ [[package]] name = "uuid-macro-internal" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d8c6bba9b149ee82950daefc9623b32bb1dacbfb1890e352f6b887bd582adaf" +checksum = "f49e7f3f3db8040a100710a11932239fd30697115e2ba4107080d8252939845e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", ] [[package]] @@ -3460,9 +3463,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3470,24 +3473,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ "cfg-if", "js-sys", @@ -3497,9 +3500,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3507,28 +3510,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.40", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-bindgen-test" -version = "0.3.37" +version = "0.3.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" +checksum = "c6433b7c56db97397842c46b67e11873eda263170afeb3a2dc74a7cb370fee0d" dependencies = [ "console_error_panic_hook", "js-sys", @@ -3540,12 +3543,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.37" +version = "0.3.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" +checksum = "493fcbab756bb764fa37e6bee8cec2dd709eb4273d06d0c282a5e74275ded735" dependencies = [ "proc-macro2", "quote", + "syn 2.0.40", ] [[package]] @@ -3642,6 +3646,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -3672,6 +3685,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -3684,6 +3712,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -3696,6 +3730,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -3708,6 +3748,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -3720,6 +3766,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -3732,6 +3784,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -3744,6 +3802,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -3756,6 +3820,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" version = "0.5.15" @@ -3794,3 +3864,23 @@ checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1" dependencies = [ "winapi", ] + +[[package]] +name = "zerocopy" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", +] diff --git a/Cargo.toml b/Cargo.toml index c52264fe4b124..aad3c664465ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,24 +17,24 @@ bitflags = { version = "2.4.1" } chrono = { version = "0.4.31", default-features = false, features = ["clock"] } clap = { version = "4.4.7", features = ["derive"] } colored = { version = "2.0.0" } -filetime = { version = "0.2.20" } +filetime = { version = "0.2.23" } glob = { version = "0.3.1" } -globset = { version = "0.4.10" } +globset = { version = "0.4.14" } ignore = { version = "0.4.20" } insta = { version = "1.34.0", feature = ["filters", "glob"] } -is-macro = { version = "0.3.0" } +is-macro = { version = "0.3.1" } itertools = { version = "0.11.0" } libcst = { version = "1.1.0", default-features = false } log = { version = "0.4.17" } memchr = { version = "2.6.4" } once_cell = { version = "1.17.1" } path-absolutize = { version = "3.1.1" } -proc-macro2 = { version = "1.0.69" } +proc-macro2 = { version = "1.0.70" } quote = { version = "1.0.23" } regex = { version = "1.10.2" } rustc-hash = { version = "1.1.0" } -schemars = { version = "0.8.15" } -serde = { version = "1.0.190", features = ["derive"] } +schemars = { version = "0.8.16" } +serde = { version = "1.0.193", features = ["derive"] } serde_json = { version = "1.0.108" } shellexpand = { version = "3.0.0" } similar = { version = "2.3.0", features = ["inline"] } @@ -42,17 +42,17 @@ smallvec = { version = "1.11.2" } static_assertions = "1.1.0" strum = { version = "0.25.0", features = ["strum_macros"] } strum_macros = { version = "0.25.3" } -syn = { version = "2.0.39" } +syn = { version = "2.0.40" } test-case = { version = "3.2.1" } thiserror = { version = "1.0.50" } toml = { version = "0.7.8" } tracing = { version = "0.1.40" } tracing-indicatif = { version = "0.3.4" } -tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } unicode-ident = { version = "1.0.12" } unicode_names2 = { version = "1.2.0" } unicode-width = { version = "0.1.11" } -uuid = { version = "1.5.0", features = ["v4", "fast-rng", "macro-diagnostics", "js"] } +uuid = { version = "1.6.1", features = ["v4", "fast-rng", "macro-diagnostics", "js"] } wsl = { version = "0.1.0" } [workspace.lints.rust] @@ -88,7 +88,20 @@ rc_mutex = "warn" rest_pat_in_fully_bound_structs = "warn" [profile.release] -lto = "fat" +# Note that we set these explicitly, and these values +# were chosen based on a trade-off between compile times +# and runtime performance[1]. +# +# [1]: https://github.com/astral-sh/ruff/pull/9031 +lto = "thin" +codegen-units = 16 + +# Some crates don't change as much but benefit more from +# more expensive optimization passes, so we selectively +# decrease codegen-units in some cases. +[profile.release.package.ruff_python_parser] +codegen-units = 1 +[profile.release.package.ruff_python_ast] codegen-units = 1 [profile.dev.package.insta] @@ -102,8 +115,8 @@ opt-level = 3 [profile.dev.package.ruff_python_parser] opt-level = 1 -# Use the `--profile release-debug` flag to show symbols in release mode. -# e.g. `cargo build --profile release-debug` -[profile.release-debug] +# Use the `--profile profiling` flag to show symbols in release mode. +# e.g. `cargo build --profile profiling` +[profile.profiling] inherits = "release" debug = 1 diff --git a/README.md b/README.md index 2cb126aea6b94..7554930ad0460 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.6 + rev: v0.1.8 hooks: # Run the linter. - id: ruff diff --git a/crates/flake8_to_ruff/Cargo.toml b/crates/flake8_to_ruff/Cargo.toml index 9d85f52c19e4f..71e5032e76aa0 100644 --- a/crates/flake8_to_ruff/Cargo.toml +++ b/crates/flake8_to_ruff/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flake8-to-ruff" -version = "0.1.6" +version = "0.1.8" description = """ Convert Flake8 configuration files to Ruff configuration files. """ @@ -19,7 +19,7 @@ ruff_workspace = { path = "../ruff_workspace" } anyhow = { workspace = true } clap = { workspace = true } colored = { workspace = true } -configparser = { version = "3.0.2" } +configparser = { version = "3.0.3" } itertools = { workspace = true } log = { workspace = true } once_cell = { workspace = true } diff --git a/crates/ruff_benchmark/Cargo.toml b/crates/ruff_benchmark/Cargo.toml index 192add9fd92ac..60f1b5011e56c 100644 --- a/crates/ruff_benchmark/Cargo.toml +++ b/crates/ruff_benchmark/Cargo.toml @@ -34,10 +34,10 @@ harness = false once_cell.workspace = true serde.workspace = true serde_json.workspace = true -url = "2.3.1" -ureq = "2.8.0" +url = "2.5.0" +ureq = "2.9.1" criterion = { version = "0.5.1", default-features = false } -codspeed-criterion-compat = { version="2.3.1", default-features = false, optional = true} +codspeed-criterion-compat = { version="2.3.3", default-features = false, optional = true} [dev-dependencies] ruff_linter.path = "../ruff_linter" diff --git a/crates/ruff_benchmark/benches/formatter.rs b/crates/ruff_benchmark/benches/formatter.rs index e89b47a102aee..17e6e2d3844e2 100644 --- a/crates/ruff_benchmark/benches/formatter.rs +++ b/crates/ruff_benchmark/benches/formatter.rs @@ -4,7 +4,7 @@ use ruff_benchmark::criterion::{ criterion_group, criterion_main, BenchmarkId, Criterion, Throughput, }; use ruff_benchmark::{TestCase, TestFile, TestFileDownloadError}; -use ruff_python_formatter::{format_module_ast, PyFormatOptions}; +use ruff_python_formatter::{format_module_ast, PreviewMode, PyFormatOptions}; use ruff_python_index::CommentRangesBuilder; use ruff_python_parser::lexer::lex; use ruff_python_parser::{parse_tokens, Mode}; @@ -69,7 +69,8 @@ fn benchmark_formatter(criterion: &mut Criterion) { .expect("Input to be a valid python program"); b.iter(|| { - let options = PyFormatOptions::from_extension(Path::new(case.name())); + let options = PyFormatOptions::from_extension(Path::new(case.name())) + .with_preview(PreviewMode::Enabled); let formatted = format_module_ast(&module, &comment_ranges, case.code(), options) .expect("Formatting to succeed"); diff --git a/crates/ruff_benchmark/benches/linter.rs b/crates/ruff_benchmark/benches/linter.rs index 9a5e01f2bf589..a98061fc822a8 100644 --- a/crates/ruff_benchmark/benches/linter.rs +++ b/crates/ruff_benchmark/benches/linter.rs @@ -3,7 +3,9 @@ use ruff_benchmark::criterion::{ }; use ruff_benchmark::{TestCase, TestFile, TestFileDownloadError}; use ruff_linter::linter::lint_only; +use ruff_linter::rule_selector::PreviewOptions; use ruff_linter::settings::rule_table::RuleTable; +use ruff_linter::settings::types::PreviewMode; use ruff_linter::settings::{flags, LinterSettings}; use ruff_linter::source_kind::SourceKind; use ruff_linter::{registry::Rule, RuleSelector}; @@ -78,12 +80,21 @@ fn benchmark_default_rules(criterion: &mut Criterion) { benchmark_linter(group, &LinterSettings::default()); } -fn benchmark_all_rules(criterion: &mut Criterion) { - let mut rules: RuleTable = RuleSelector::All.all_rules().collect(); - - // Disable IO based rules because it is a source of flakiness +/// Disables IO based rules because they are a source of flakiness +fn disable_io_rules(rules: &mut RuleTable) { rules.disable(Rule::ShebangMissingExecutableFile); rules.disable(Rule::ShebangNotExecutable); +} + +fn benchmark_all_rules(criterion: &mut Criterion) { + let mut rules: RuleTable = RuleSelector::All + .rules(&PreviewOptions { + mode: PreviewMode::Disabled, + require_explicit: false, + }) + .collect(); + + disable_io_rules(&mut rules); let settings = LinterSettings { rules, @@ -94,6 +105,22 @@ fn benchmark_all_rules(criterion: &mut Criterion) { benchmark_linter(group, &settings); } +fn benchmark_preview_rules(criterion: &mut Criterion) { + let mut rules: RuleTable = RuleSelector::All.all_rules().collect(); + + disable_io_rules(&mut rules); + + let settings = LinterSettings { + rules, + preview: PreviewMode::Enabled, + ..LinterSettings::default() + }; + + let group = criterion.benchmark_group("linter/all-with-preview-rules"); + benchmark_linter(group, &settings); +} + criterion_group!(default_rules, benchmark_default_rules); criterion_group!(all_rules, benchmark_all_rules); -criterion_main!(default_rules, all_rules); +criterion_group!(preview_rules, benchmark_preview_rules); +criterion_main!(default_rules, all_rules, preview_rules); diff --git a/crates/ruff_cli/Cargo.toml b/crates/ruff_cli/Cargo.toml index 84bfcb5f6683f..ded05207e05a5 100644 --- a/crates/ruff_cli/Cargo.toml +++ b/crates/ruff_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff_cli" -version = "0.1.6" +version = "0.1.8" publish = false authors = { workspace = true } edition = { workspace = true } @@ -69,7 +69,7 @@ insta = { workspace = true, features = ["filters", "json"] } insta-cmd = { version = "0.4.0" } tempfile = "3.8.1" test-case = { workspace = true } -ureq = { version = "2.8.0", features = [] } +ureq = { version = "2.9.1", features = [] } [target.'cfg(target_os = "windows")'.dependencies] mimalloc = "0.1.39" diff --git a/crates/ruff_cli/resources/test/fixtures/include-test/a.py b/crates/ruff_cli/resources/test/fixtures/include-test/a.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/crates/ruff_cli/resources/test/fixtures/include-test/b.py b/crates/ruff_cli/resources/test/fixtures/include-test/b.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/crates/ruff_cli/resources/test/fixtures/include-test/nested-project/e.py b/crates/ruff_cli/resources/test/fixtures/include-test/nested-project/e.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/crates/ruff_cli/resources/test/fixtures/include-test/nested-project/pyproject.toml b/crates/ruff_cli/resources/test/fixtures/include-test/nested-project/pyproject.toml new file mode 100644 index 0000000000000..acbc6447e5fad --- /dev/null +++ b/crates/ruff_cli/resources/test/fixtures/include-test/nested-project/pyproject.toml @@ -0,0 +1,2 @@ +[tool.ruff] +select = [] diff --git a/crates/ruff_cli/resources/test/fixtures/include-test/pyproject.toml b/crates/ruff_cli/resources/test/fixtures/include-test/pyproject.toml new file mode 100644 index 0000000000000..fadb2359fba35 --- /dev/null +++ b/crates/ruff_cli/resources/test/fixtures/include-test/pyproject.toml @@ -0,0 +1,2 @@ +[tool.ruff] +include = ["a.py", "subdirectory/c.py"] \ No newline at end of file diff --git a/crates/ruff_cli/resources/test/fixtures/include-test/subdirectory/c.py b/crates/ruff_cli/resources/test/fixtures/include-test/subdirectory/c.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/crates/ruff_cli/resources/test/fixtures/include-test/subdirectory/d.py b/crates/ruff_cli/resources/test/fixtures/include-test/subdirectory/d.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/crates/ruff_cli/src/args.rs b/crates/ruff_cli/src/args.rs index d14c0a965870c..6c5ed14456ab9 100644 --- a/crates/ruff_cli/src/args.rs +++ b/crates/ruff_cli/src/args.rs @@ -88,6 +88,7 @@ pub enum Command { #[allow(clippy::struct_excessive_bools)] pub struct CheckCommand { /// List of files or directories to check. + #[clap(help = "List of files or directories to check [default: .]")] pub files: Vec, /// Apply fixes to resolve lint violations. /// Use `--no-fix` to disable or `--unsafe-fixes` to include unsafe fixes. @@ -363,6 +364,7 @@ pub struct CheckCommand { #[allow(clippy::struct_excessive_bools)] pub struct FormatCommand { /// List of files or directories to format. + #[clap(help = "List of files or directories to format [default: .]")] pub files: Vec, /// Avoid writing any formatted files back; instead, exit with a non-zero status code if any /// files would have been modified, and zero otherwise. diff --git a/crates/ruff_cli/src/commands/format.rs b/crates/ruff_cli/src/commands/format.rs index 1b2e431b8ecb4..697c412163cf8 100644 --- a/crates/ruff_cli/src/commands/format.rs +++ b/crates/ruff_cli/src/commands/format.rs @@ -34,7 +34,7 @@ use crate::args::{CliOverrides, FormatArguments}; use crate::cache::{Cache, FileCacheKey, PackageCacheMap, PackageCaches}; use crate::panic::{catch_unwind, PanicError}; use crate::resolve::resolve; -use crate::ExitStatus; +use crate::{resolve_default_files, ExitStatus}; #[derive(Debug, Copy, Clone, is_macro::Is)] pub(crate) enum FormatMode { @@ -60,7 +60,7 @@ impl FormatMode { /// Format a set of files, and return the exit status. pub(crate) fn format( - cli: &FormatArguments, + cli: FormatArguments, overrides: &CliOverrides, log_level: LogLevel, ) -> Result { @@ -70,8 +70,9 @@ pub(crate) fn format( overrides, cli.stdin_filename.as_deref(), )?; - let mode = FormatMode::from_cli(cli); - let (paths, resolver) = python_files_in_path(&cli.files, &pyproject_config, overrides)?; + let mode = FormatMode::from_cli(&cli); + let files = resolve_default_files(cli.files, false); + let (paths, resolver) = python_files_in_path(&files, &pyproject_config, overrides)?; if paths.is_empty() { warn_user_once!("No Python files found under the given path(s)"); diff --git a/crates/ruff_cli/src/lib.rs b/crates/ruff_cli/src/lib.rs index 4cb0db0c8bb9e..f8f99505b3c91 100644 --- a/crates/ruff_cli/src/lib.rs +++ b/crates/ruff_cli/src/lib.rs @@ -101,6 +101,19 @@ fn is_stdin(files: &[PathBuf], stdin_filename: Option<&Path>) -> bool { file == Path::new("-") } +/// Returns the default set of files if none are provided, otherwise returns `None`. +fn resolve_default_files(files: Vec, is_stdin: bool) -> Vec { + if files.is_empty() { + if is_stdin { + vec![Path::new("-").to_path_buf()] + } else { + vec![Path::new(".").to_path_buf()] + } + } else { + files + } +} + /// Get the actual value of the `format` desired from either `output_format` /// or `format`, and warn the user if they're using the deprecated form. fn resolve_help_output_format(output_format: HelpFormat, format: Option) -> HelpFormat { @@ -196,7 +209,7 @@ fn format(args: FormatCommand, log_level: LogLevel) -> Result { if is_stdin(&cli.files, cli.stdin_filename.as_deref()) { commands::format_stdin::format_stdin(&cli, &overrides) } else { - commands::format::format(&cli, &overrides, log_level) + commands::format::format(cli, &overrides, log_level) } } @@ -222,17 +235,15 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { }; let stderr_writer = Box::new(BufWriter::new(io::stderr())); + let is_stdin = is_stdin(&cli.files, cli.stdin_filename.as_deref()); + let files = resolve_default_files(cli.files, is_stdin); + if cli.show_settings { - commands::show_settings::show_settings( - &cli.files, - &pyproject_config, - &overrides, - &mut writer, - )?; + commands::show_settings::show_settings(&files, &pyproject_config, &overrides, &mut writer)?; return Ok(ExitStatus::Success); } if cli.show_files { - commands::show_files::show_files(&cli.files, &pyproject_config, &overrides, &mut writer)?; + commands::show_files::show_files(&files, &pyproject_config, &overrides, &mut writer)?; return Ok(ExitStatus::Success); } @@ -295,8 +306,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { if !fix_mode.is_generate() { warn_user!("--fix is incompatible with --add-noqa."); } - let modifications = - commands::add_noqa::add_noqa(&cli.files, &pyproject_config, &overrides)?; + let modifications = commands::add_noqa::add_noqa(&files, &pyproject_config, &overrides)?; if modifications > 0 && log_level >= LogLevel::Default { let s = if modifications == 1 { "" } else { "s" }; #[allow(clippy::print_stderr)] @@ -323,7 +333,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { // Configure the file watcher. let (tx, rx) = channel(); let mut watcher = recommended_watcher(tx)?; - for file in &cli.files { + for file in &files { watcher.watch(file, RecursiveMode::Recursive)?; } if let Some(file) = pyproject_config.path.as_ref() { @@ -335,7 +345,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { printer.write_to_user("Starting linter in watch mode...\n"); let messages = commands::check::check( - &cli.files, + &files, &pyproject_config, &overrides, cache.into(), @@ -368,7 +378,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { printer.write_to_user("File change detected...\n"); let messages = commands::check::check( - &cli.files, + &files, &pyproject_config, &overrides, cache.into(), @@ -382,8 +392,6 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { } } } else { - let is_stdin = is_stdin(&cli.files, cli.stdin_filename.as_deref()); - // Generate lint violations. let diagnostics = if is_stdin { commands::check_stdin::check_stdin( @@ -395,7 +403,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { )? } else { commands::check::check( - &cli.files, + &files, &pyproject_config, &overrides, cache.into(), diff --git a/crates/ruff_cli/src/printer.rs b/crates/ruff_cli/src/printer.rs index 6f22f37d1608e..5bfdece63beaa 100644 --- a/crates/ruff_cli/src/printer.rs +++ b/crates/ruff_cli/src/printer.rs @@ -13,7 +13,7 @@ use ruff_linter::fs::relativize_path; use ruff_linter::logging::LogLevel; use ruff_linter::message::{ AzureEmitter, Emitter, EmitterContext, GithubEmitter, GitlabEmitter, GroupedEmitter, - JsonEmitter, JsonLinesEmitter, JunitEmitter, PylintEmitter, TextEmitter, + JsonEmitter, JsonLinesEmitter, JunitEmitter, PylintEmitter, SarifEmitter, TextEmitter, }; use ruff_linter::notify_user; use ruff_linter::registry::{AsRule, Rule}; @@ -125,15 +125,7 @@ impl Printer { if let Some(fixables) = fixables { let fix_prefix = format!("[{}]", "*".cyan()); - if self.unsafe_fixes.is_enabled() { - if fixables.applicable > 0 { - writeln!( - writer, - "{fix_prefix} {} fixable with the --fix option.", - fixables.applicable - )?; - } - } else { + if self.unsafe_fixes.is_hint() { if fixables.applicable > 0 && fixables.unapplicable_unsafe > 0 { let es = if fixables.unapplicable_unsafe == 1 { "" @@ -163,6 +155,14 @@ impl Printer { fixables.unapplicable_unsafe )?; } + } else { + if fixables.applicable > 0 { + writeln!( + writer, + "{fix_prefix} {} fixable with the --fix option.", + fixables.applicable + )?; + } } } } else { @@ -291,6 +291,9 @@ impl Printer { SerializationFormat::Azure => { AzureEmitter.emit(writer, &diagnostics.messages, &context)?; } + SerializationFormat::Sarif => { + SarifEmitter.emit(writer, &diagnostics.messages, &context)?; + } } writer.flush()?; diff --git a/crates/ruff_cli/tests/format.rs b/crates/ruff_cli/tests/format.rs index c5c399563330a..cd3e14629899e 100644 --- a/crates/ruff_cli/tests/format.rs +++ b/crates/ruff_cli/tests/format.rs @@ -43,6 +43,53 @@ if condition: "###); } +#[test] +fn default_files() -> Result<()> { + let tempdir = TempDir::new()?; + fs::write( + tempdir.path().join("foo.py"), + r#" +foo = "needs formatting" +"#, + )?; + fs::write( + tempdir.path().join("bar.py"), + r#" +bar = "needs formatting" +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["format", "--isolated", "--no-cache", "--check"]).current_dir(tempdir.path()), @r###" + success: false + exit_code: 1 + ----- stdout ----- + Would reformat: bar.py + Would reformat: foo.py + 2 files would be reformatted + + ----- stderr ----- + "###); + + Ok(()) +} + +#[test] +fn format_warn_stdin_filename_with_files() { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["format", "--isolated", "--stdin-filename", "foo.py"]) + .arg("foo.py") + .pass_stdin("foo = 1"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + foo = 1 + + ----- stderr ----- + warning: Ignoring file foo.py in favor of standard input. + "###); +} + #[test] fn format_options() -> Result<()> { let tempdir = TempDir::new()?; @@ -92,6 +139,99 @@ if condition: Ok(()) } +#[test] +fn docstring_options() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[format] +docstring-code-format = true +docstring-code-line-length = 20 +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["format", "--config"]) + .arg(&ruff_toml) + .arg("-") + .pass_stdin(r#" +def f(x): + ''' + Something about `f`. And an example: + + .. code-block:: python + + foo, bar, quux = this_is_a_long_line(lion, hippo, lemur, bear) + + Another example: + + ```py + foo, bar, quux = this_is_a_long_line(lion, hippo, lemur, bear) + ``` + + And another: + + >>> foo, bar, quux = this_is_a_long_line(lion, hippo, lemur, bear) + ''' + pass +"#), @r###" +success: true +exit_code: 0 +----- stdout ----- +def f(x): + """ + Something about `f`. And an example: + + .. code-block:: python + + ( + foo, + bar, + quux, + ) = this_is_a_long_line( + lion, + hippo, + lemur, + bear, + ) + + Another example: + + ```py + ( + foo, + bar, + quux, + ) = this_is_a_long_line( + lion, + hippo, + lemur, + bear, + ) + ``` + + And another: + + >>> ( + ... foo, + ... bar, + ... quux, + ... ) = this_is_a_long_line( + ... lion, + ... hippo, + ... lemur, + ... bear, + ... ) + """ + pass + +----- stderr ----- +"###); + Ok(()) +} + #[test] fn mixed_line_endings() -> Result<()> { let tempdir = TempDir::new()?; diff --git a/crates/ruff_cli/tests/integration_test.rs b/crates/ruff_cli/tests/integration_test.rs index 59c372aac1806..1ee634f6c09d3 100644 --- a/crates/ruff_cli/tests/integration_test.rs +++ b/crates/ruff_cli/tests/integration_test.rs @@ -5,7 +5,6 @@ use std::fs; use std::fs::Permissions; #[cfg(unix)] use std::os::unix::fs::{OpenOptionsExt, PermissionsExt}; -#[cfg(unix)] use std::path::Path; use std::process::Command; use std::str; @@ -26,12 +25,84 @@ use ruff_cli::args::Args; use ruff_cli::run; const BIN_NAME: &str = "ruff"; -const STDIN_BASE_OPTIONS: &[&str] = &["--isolated", "--no-cache", "-", "--output-format", "text"]; + +fn ruff_cmd() -> Command { + Command::new(get_cargo_bin(BIN_NAME)) +} + +/// Builder for `ruff check` commands. +#[derive(Debug)] +struct RuffCheck<'a> { + output_format: &'a str, + config: Option<&'a Path>, + filename: Option<&'a str>, + args: Vec<&'a str>, +} + +impl<'a> Default for RuffCheck<'a> { + fn default() -> RuffCheck<'a> { + RuffCheck { + output_format: "text", + config: None, + filename: None, + args: vec![], + } + } +} + +impl<'a> RuffCheck<'a> { + /// Set the `--config` option. + #[must_use] + fn config(mut self, config: &'a Path) -> Self { + self.config = Some(config); + self + } + + /// Set the `--output-format` option. + #[must_use] + fn output_format(mut self, format: &'a str) -> Self { + self.output_format = format; + self + } + + /// Set the input file to pass to `ruff check`. + #[must_use] + fn filename(mut self, filename: &'a str) -> Self { + self.filename = Some(filename); + self + } + + /// Set the list of positional arguments. + #[must_use] + fn args(mut self, args: impl IntoIterator) -> Self { + self.args = args.into_iter().collect(); + self + } + + /// Generate a [`Command`] for the `ruff check` command. + fn build(self) -> Command { + let mut cmd = ruff_cmd(); + cmd.args(["--output-format", self.output_format, "--no-cache"]); + if let Some(path) = self.config { + cmd.arg("--config"); + cmd.arg(path); + } else { + cmd.arg("--isolated"); + } + if let Some(filename) = self.filename { + cmd.arg(filename); + } else { + cmd.arg("-"); + } + cmd.args(self.args); + cmd + } +} #[test] fn stdin_success() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) + let mut cmd = RuffCheck::default().args([]).build(); + assert_cmd_snapshot!(cmd .pass_stdin(""), @r###" success: true exit_code: 0 @@ -43,8 +114,8 @@ fn stdin_success() { #[test] fn stdin_error() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) + let mut cmd = RuffCheck::default().args([]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("import os\n"), @r###" success: false exit_code: 1 @@ -59,9 +130,61 @@ fn stdin_error() { #[test] fn stdin_filename() { + let mut cmd = RuffCheck::default() + .args(["--stdin-filename", "F401.py"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("import os\n"), @r###" + success: false + exit_code: 1 + ----- stdout ----- + F401.py:1:8: F401 [*] `os` imported but unused + Found 1 error. + [*] 1 fixable with the `--fix` option. + + ----- stderr ----- + "###); +} + +#[test] +fn check_default_files() -> Result<()> { + let tempdir = TempDir::new()?; + fs::write( + tempdir.path().join("foo.py"), + r#" +import foo # unused import +"#, + )?; + fs::write( + tempdir.path().join("bar.py"), + r#" +import bar # unused import +"#, + )?; + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) + .args(["check", "--isolated", "--no-cache", "--select", "F401"]).current_dir(tempdir.path()), @r###" + success: false + exit_code: 1 + ----- stdout ----- + bar.py:2:8: F401 [*] `bar` imported but unused + foo.py:2:8: F401 [*] `foo` imported but unused + Found 2 errors. + [*] 2 fixable with the `--fix` option. + + ----- stderr ----- + "###); + + Ok(()) +} + +#[test] +fn check_warn_stdin_filename_with_files() { + let mut cmd = RuffCheck::default() .args(["--stdin-filename", "F401.py"]) + .filename("foo.py") + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("import os\n"), @r###" success: false exit_code: 1 @@ -71,15 +194,17 @@ fn stdin_filename() { [*] 1 fixable with the `--fix` option. ----- stderr ----- + warning: Ignoring file foo.py in favor of standard input. "###); } /// Raise `TCH` errors in `.py` files ... #[test] fn stdin_source_type_py() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) + let mut cmd = RuffCheck::default() .args(["--stdin-filename", "TCH.py"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("import os\n"), @r###" success: false exit_code: 1 @@ -95,10 +220,10 @@ fn stdin_source_type_py() { /// ... but not in `.pyi` files. #[test] fn stdin_source_type_pyi() { - let args = ["--stdin-filename", "TCH.pyi", "--select", "TCH"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--stdin-filename", "TCH.pyi", "--select", "TCH"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("import os\n"), @r###" success: true exit_code: 0 @@ -111,35 +236,26 @@ fn stdin_source_type_pyi() { #[cfg(unix)] #[test] fn stdin_json() { - let args = [ - "-", - "--isolated", - "--no-cache", - "--output-format", - "json", - "--stdin-filename", - "F401.py", - ]; - let directory = path_dedot::CWD.to_str().unwrap(); let binding = Path::new(directory).join("F401.py"); let file_path = binding.display(); + let mut cmd = RuffCheck::default() + .output_format("json") + .args(["--stdin-filename", "F401.py"]) + .build(); + insta::with_settings!({filters => vec![ (file_path.to_string().as_str(), "/path/to/F401.py"), ]}, { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(args) - .pass_stdin("import os\n")); + assert_cmd_snapshot!(cmd.pass_stdin("import os\n")); }); } #[test] fn stdin_fix_py() { - let args = ["--fix"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--fix"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("import os\nimport sys\n\nprint(sys.version)\n"), @r###" success: true exit_code: 0 @@ -155,10 +271,10 @@ fn stdin_fix_py() { #[test] fn stdin_fix_jupyter() { - let args = ["--fix", "--stdin-filename", "Jupyter.ipynb"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--fix", "--stdin-filename", "Jupyter.ipynb"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin(r#"{ "cells": [ { @@ -320,12 +436,13 @@ fn stdin_fix_jupyter() { Found 2 errors (2 fixed, 0 remaining). "###); } + #[test] fn stdin_override_parser_ipynb() { - let args = ["--extension", "py:ipynb", "--stdin-filename", "Jupyter.py"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--extension", "py:ipynb", "--stdin-filename", "Jupyter.py"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin(r#"{ "cells": [ { @@ -419,9 +536,15 @@ fn stdin_override_parser_ipynb() { #[test] fn stdin_override_parser_py() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(["--extension", "ipynb:python", "--stdin-filename", "F401.ipynb"]) + let mut cmd = RuffCheck::default() + .args([ + "--extension", + "ipynb:python", + "--stdin-filename", + "F401.ipynb", + ]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("import os\n"), @r###" success: false exit_code: 1 @@ -436,10 +559,8 @@ fn stdin_override_parser_py() { #[test] fn stdin_fix_when_not_fixable_should_still_print_contents() { - let args = ["--fix"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--fix"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("import os\nimport sys\n\nif (1, 2):\n print(sys.version)\n"), @r###" success: false exit_code: 1 @@ -457,10 +578,8 @@ fn stdin_fix_when_not_fixable_should_still_print_contents() { #[test] fn stdin_fix_when_no_issues_should_still_print_contents() { - let args = ["--fix"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--fix"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("import sys\n\nprint(sys.version)\n"), @r###" success: true exit_code: 0 @@ -475,9 +594,8 @@ fn stdin_fix_when_no_issues_should_still_print_contents() { #[test] fn stdin_format_jupyter() { - let args = ["format", "--stdin-filename", "Jupyter.ipynb", "--isolated"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(args) + assert_cmd_snapshot!(ruff_cmd() + .args(["format", "--stdin-filename", "Jupyter.ipynb", "--isolated"]) .pass_stdin(r#"{ "cells": [ { @@ -603,10 +721,8 @@ fn stdin_format_jupyter() { #[test] fn show_source() { - let args = ["--show-source"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--show-source"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("l = 1"), @r###" success: false exit_code: 1 @@ -625,11 +741,11 @@ fn show_source() { #[test] fn explain_status_codes_f401() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)).args(["--explain", "F401"])); + assert_cmd_snapshot!(ruff_cmd().args(["--explain", "F401"])); } #[test] fn explain_status_codes_ruf404() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)).args(["--explain", "RUF404"]), @r###" + assert_cmd_snapshot!(ruff_cmd().args(["--explain", "RUF404"]), @r###" success: false exit_code: 2 ----- stdout ----- @@ -643,10 +759,10 @@ fn explain_status_codes_ruf404() { #[test] fn show_statistics() { - let args = ["--select", "F401", "--statistics"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--select", "F401", "--statistics"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("import sys\nimport os\n\nprint(os.getuid())\n"), @r###" success: false exit_code: 1 @@ -660,10 +776,8 @@ fn show_statistics() { #[test] fn nursery_prefix() { // `--select E` should detect E741, but not E225, which is in the nursery. - let args = ["--select", "E"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--select", "E"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -678,10 +792,8 @@ fn nursery_prefix() { #[test] fn nursery_all() { // `--select ALL` should detect E741, but not E225, which is in the nursery. - let args = ["--select", "ALL"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--select", "ALL"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -699,10 +811,8 @@ fn nursery_all() { #[test] fn nursery_direct() { // `--select E225` should detect E225. - let args = ["--select", "E225"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--select", "E225"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -718,10 +828,8 @@ fn nursery_direct() { #[test] fn nursery_group_selector() { // Only nursery rules should be detected e.g. E225 and a warning should be displayed - let args = ["--select", "NURSERY"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--select", "NURSERY"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -738,10 +846,10 @@ fn nursery_group_selector() { #[test] fn nursery_group_selector_preview_enabled() { // Only nursery rules should be detected e.g. E225 and a warning should be displayed - let args = ["--select", "NURSERY", "--preview"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--select", "NURSERY", "--preview"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -759,10 +867,10 @@ fn nursery_group_selector_preview_enabled() { #[test] fn preview_enabled_prefix() { // E741 and E225 (preview) should both be detected - let args = ["--select", "E", "--preview"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--select", "E", "--preview"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -778,10 +886,10 @@ fn preview_enabled_prefix() { #[test] fn preview_enabled_all() { - let args = ["--select", "ALL", "--preview"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--select", "ALL", "--preview"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -802,10 +910,10 @@ fn preview_enabled_all() { #[test] fn preview_enabled_direct() { // E225 should be detected without warning - let args = ["--select", "E225", "--preview"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--select", "E225", "--preview"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -821,10 +929,8 @@ fn preview_enabled_direct() { #[test] fn preview_disabled_direct() { // FURB145 is preview not nursery so selecting should be empty - let args = ["--select", "FURB145"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--select", "FURB145"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("a = l[:]\n"), @r###" success: true exit_code: 0 @@ -838,10 +944,8 @@ fn preview_disabled_direct() { #[test] fn preview_disabled_prefix_empty() { // Warns that the selection is empty since all of the CPY rules are in preview - let args = ["--select", "CPY"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--select", "CPY"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: true exit_code: 0 @@ -855,10 +959,8 @@ fn preview_disabled_prefix_empty() { #[test] fn preview_disabled_does_not_warn_for_empty_ignore_selections() { // Does not warn that the selection is empty since the user is not trying to enable the rule - let args = ["--ignore", "CPY"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--ignore", "CPY"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -873,10 +975,8 @@ fn preview_disabled_does_not_warn_for_empty_ignore_selections() { #[test] fn preview_disabled_does_not_warn_for_empty_fixable_selections() { // Does not warn that the selection is empty since the user is not trying to enable the rule - let args = ["--fixable", "CPY"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default().args(["--fixable", "CPY"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 1 @@ -891,10 +991,10 @@ fn preview_disabled_does_not_warn_for_empty_fixable_selections() { #[test] fn preview_group_selector() { // `--select PREVIEW` should error (selector was removed) - let args = ["--select", "PREVIEW", "--preview"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--select", "PREVIEW", "--preview"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 2 @@ -910,10 +1010,10 @@ fn preview_group_selector() { #[test] fn preview_enabled_group_ignore() { // `--select E --ignore PREVIEW` should detect E741 and E225, which is in preview but "E" is more specific. - let args = ["--select", "E", "--ignore", "PREVIEW", "--preview"]; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(args) + let mut cmd = RuffCheck::default() + .args(["--select", "E", "--ignore", "PREVIEW", "--preview"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("I=42\n"), @r###" success: false exit_code: 2 @@ -965,9 +1065,11 @@ fn unreadable_dir() -> Result<()> { // We (currently?) have to use a subcommand to check exit status (currently wrong) and logging // output // TODO(konstin): This should be a failure, but we currently can't track that - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["--no-cache", "--isolated"]) - .arg(&unreadable_dir), @r###" + let mut cmd = RuffCheck::default() + .filename(unreadable_dir.to_str().unwrap()) + .args([]) + .build(); + assert_cmd_snapshot!(cmd, @r###" success: true exit_code: 0 ----- stdout ----- @@ -998,18 +1100,12 @@ fn check_input_from_argfile() -> Result<()> { )?; // Generate the args with the argfile notation - let args = vec![ - "check".to_string(), - "--no-cache".to_string(), - "--isolated".to_string(), - format!("@{}", &input_file_path.display()), - ]; - + let argfile = format!("@{}", &input_file_path.display()); + let mut cmd = RuffCheck::default().filename(argfile.as_ref()).build(); insta::with_settings!({filters => vec![ (file_a_path.display().to_string().as_str(), "/path/to/a.py"), ]}, { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(args) + assert_cmd_snapshot!(cmd .pass_stdin(""), @r###" success: false exit_code: 1 @@ -1027,15 +1123,10 @@ fn check_input_from_argfile() -> Result<()> { #[test] fn check_hints_hidden_unsafe_fixes() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format=text", - "--isolated", - "--select", - "F601,UP034", - "--no-cache", - ]) + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), @r###" success: false @@ -1052,8 +1143,8 @@ fn check_hints_hidden_unsafe_fixes() { #[test] fn check_hints_hidden_unsafe_fixes_with_no_safe_fixes() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["-", "--output-format", "text", "--no-cache", "--isolated", "--select", "F601"]) + let mut cmd = RuffCheck::default().args(["--select", "F601"]).build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\n"), @r###" success: false @@ -1067,18 +1158,50 @@ fn check_hints_hidden_unsafe_fixes_with_no_safe_fixes() { "###); } +#[test] +fn check_no_hint_for_hidden_unsafe_fixes_when_disabled() { + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034", "--no-unsafe-fixes"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:14: F601 Dictionary key literal `'a'` repeated + -:2:7: UP034 [*] Avoid extraneous parentheses + Found 2 errors. + [*] 1 fixable with the --fix option. + + ----- stderr ----- + "###); +} + +#[test] +fn check_no_hint_for_hidden_unsafe_fixes_with_no_safe_fixes_when_disabled() { + let mut cmd = RuffCheck::default() + .args(["--select", "F601", "--no-unsafe-fixes"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("x = {'a': 1, 'a': 1}\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:14: F601 Dictionary key literal `'a'` repeated + Found 1 error. + + ----- stderr ----- + "###); +} + #[test] fn check_shows_unsafe_fixes_with_opt_in() { - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format=text", - "--isolated", - "--select", - "F601,UP034", - "--no-cache", - "--unsafe-fixes", - ]) + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034", "--unsafe-fixes"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), @r###" success: false @@ -1095,20 +1218,12 @@ fn check_shows_unsafe_fixes_with_opt_in() { #[test] fn fix_applies_safe_fixes_by_default() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "F601,UP034", - "--fix", - ]) - .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034", "--fix"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" success: false exit_code: 1 ----- stdout ----- @@ -1124,21 +1239,12 @@ fn fix_applies_safe_fixes_by_default() { #[test] fn fix_applies_unsafe_fixes_with_opt_in() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "F601,UP034", - "--fix", - "--unsafe-fixes", - ]) - .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034", "--fix", "--unsafe-fixes"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" success: true exit_code: 0 ----- stdout ----- @@ -1152,20 +1258,12 @@ fn fix_applies_unsafe_fixes_with_opt_in() { #[test] fn fix_does_not_apply_display_only_fixes() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "B006", - "--fix", - ]) - .pass_stdin("def add_to_list(item, some_list=[]): ..."), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "B006", "--fix"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("def add_to_list(item, some_list=[]): ..."), + @r###" success: false exit_code: 1 ----- stdout ----- @@ -1178,21 +1276,12 @@ fn fix_does_not_apply_display_only_fixes() { #[test] fn fix_does_not_apply_display_only_fixes_with_unsafe_fixes_enabled() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "B006", - "--fix", - "--unsafe-fixes", - ]) - .pass_stdin("def add_to_list(item, some_list=[]): ..."), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "B006", "--fix", "--unsafe-fixes"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("def add_to_list(item, some_list=[]): ..."), + @r###" success: false exit_code: 1 ----- stdout ----- @@ -1205,20 +1294,12 @@ fn fix_does_not_apply_display_only_fixes_with_unsafe_fixes_enabled() { #[test] fn fix_only_unsafe_fixes_available() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "F601", - "--fix", - ]) - .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "F601", "--fix"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" success: false exit_code: 1 ----- stdout ----- @@ -1234,20 +1315,12 @@ fn fix_only_unsafe_fixes_available() { #[test] fn fix_only_flag_applies_safe_fixes_by_default() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "F601,UP034", - "--fix-only", - ]) - .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034", "--fix-only"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" success: true exit_code: 0 ----- stdout ----- @@ -1261,21 +1334,12 @@ fn fix_only_flag_applies_safe_fixes_by_default() { #[test] fn fix_only_flag_applies_unsafe_fixes_with_opt_in() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "F601,UP034", - "--fix-only", - "--unsafe-fixes", - ]) - .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034", "--fix-only", "--unsafe-fixes"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" success: true exit_code: 0 ----- stdout ----- @@ -1289,18 +1353,10 @@ fn fix_only_flag_applies_unsafe_fixes_with_opt_in() { #[test] fn diff_shows_safe_fixes_by_default() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "F601,UP034", - "--diff", - ]) + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034", "--diff"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), @r###" success: false @@ -1320,21 +1376,12 @@ fn diff_shows_safe_fixes_by_default() { #[test] fn diff_shows_unsafe_fixes_with_opt_in() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "F601,UP034", - "--diff", - "--unsafe-fixes", - ]) - .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "F601,UP034", "--diff", "--unsafe-fixes"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" success: false exit_code: 1 ----- stdout ----- @@ -1353,21 +1400,12 @@ fn diff_shows_unsafe_fixes_with_opt_in() { #[test] fn diff_does_not_show_display_only_fixes_with_unsafe_fixes_enabled() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "B006", - "--diff", - "--unsafe-fixes", - ]) - .pass_stdin("def add_to_list(item, some_list=[]): ..."), - @r###" + let mut cmd = RuffCheck::default() + .args(["--select", "B006", "--diff", "--unsafe-fixes"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("def add_to_list(item, some_list=[]): ..."), + @r###" success: true exit_code: 0 ----- stdout ----- @@ -1378,18 +1416,10 @@ fn diff_does_not_show_display_only_fixes_with_unsafe_fixes_enabled() { #[test] fn diff_only_unsafe_fixes_available() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args([ - "-", - "--output-format", - "text", - "--isolated", - "--no-cache", - "--select", - "F601", - "--diff", - ]) + let mut cmd = RuffCheck::default() + .args(["--select", "F601", "--diff"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), @r###" success: true @@ -1414,17 +1444,11 @@ extend-unsafe-fixes = ["UP034"] "#, )?; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["check", "--config"]) - .arg(&ruff_toml) - .arg("-") - .args([ - "--output-format", - "text", - "--no-cache", - "--select", - "F601,UP034", - ]) + let mut cmd = RuffCheck::default() + .config(&ruff_toml) + .args(["--select", "F601,UP034"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), @r###" success: false @@ -1453,17 +1477,11 @@ extend-safe-fixes = ["F601"] "#, )?; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["check", "--config"]) - .arg(&ruff_toml) - .arg("-") - .args([ - "--output-format", - "text", - "--no-cache", - "--select", - "F601,UP034", - ]) + let mut cmd = RuffCheck::default() + .config(&ruff_toml) + .args(["--select", "F601,UP034"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), @r###" success: false @@ -1494,17 +1512,11 @@ extend-safe-fixes = ["UP034"] "#, )?; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["check", "--config"]) - .arg(&ruff_toml) - .arg("-") - .args([ - "--output-format", - "text", - "--no-cache", - "--select", - "F601,UP034", - ]) + let mut cmd = RuffCheck::default() + .config(&ruff_toml) + .args(["--select", "F601,UP034"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), @r###" success: false @@ -1536,17 +1548,11 @@ extend-safe-fixes = ["UP03"] "#, )?; - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["check", "--config"]) - .arg(&ruff_toml) - .arg("-") - .args([ - "--output-format", - "text", - "--no-cache", - "--select", - "F601,UP018,UP034,UP038", - ]) + let mut cmd = RuffCheck::default() + .config(&ruff_toml) + .args(["--select", "F601,UP018,UP034,UP038"]) + .build(); + assert_cmd_snapshot!(cmd .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\nprint(str('foo'))\nisinstance(x, (int, str))\n"), @r###" success: false @@ -1591,12 +1597,12 @@ def log(x, base) -> float: "#; // If we only select the prefix, then everything passes - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["check", "-", "--config"]) - .arg(&ruff_toml) - .args(["--output-format", "text", "--no-cache", "--select", "D41"]) - .pass_stdin(stdin), - @r###" + let mut cmd = RuffCheck::default() + .config(&ruff_toml) + .args(["--select", "D41"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin(stdin), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1606,12 +1612,12 @@ def log(x, base) -> float: ); // But if we select the exact code, we get an error - assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["check", "-", "--config"]) - .arg(&ruff_toml) - .args(["--output-format", "text", "--no-cache", "--select", "D417"]) - .pass_stdin(stdin), - @r###" + let mut cmd = RuffCheck::default() + .config(&ruff_toml) + .args(["--select", "D417"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin(stdin), @r###" success: false exit_code: 1 ----- stdout ----- diff --git a/crates/ruff_cli/tests/lint.rs b/crates/ruff_cli/tests/lint.rs index f36f612ba8919..5dfbd56f83c55 100644 --- a/crates/ruff_cli/tests/lint.rs +++ b/crates/ruff_cli/tests/lint.rs @@ -396,3 +396,43 @@ if __name__ == "__main__": "###); Ok(()) } + +/// Regression test for [#8858](https://github.com/astral-sh/ruff/issues/8858) +#[test] +fn parent_configuration_override() -> Result<()> { + let tempdir = TempDir::new()?; + let root_ruff = tempdir.path().join("ruff.toml"); + fs::write( + root_ruff, + r#" +[lint] +select = ["ALL"] +"#, + )?; + + let sub_dir = tempdir.path().join("subdirectory"); + fs::create_dir(&sub_dir)?; + + let subdirectory_ruff = sub_dir.join("ruff.toml"); + fs::write( + subdirectory_ruff, + r#" +[lint] +ignore = ["D203", "D212"] +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .current_dir(sub_dir) + .arg("check") + .args(STDIN_BASE_OPTIONS) + , @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: No Python files found under the given path(s) + "###); + Ok(()) +} diff --git a/crates/ruff_cli/tests/resolve_files.rs b/crates/ruff_cli/tests/resolve_files.rs new file mode 100644 index 0000000000000..b9f75a8760b2a --- /dev/null +++ b/crates/ruff_cli/tests/resolve_files.rs @@ -0,0 +1,101 @@ +#![cfg(not(target_family = "wasm"))] + +use std::path::Path; +use std::process::Command; +use std::str; + +use insta_cmd::{assert_cmd_snapshot, get_cargo_bin}; +const BIN_NAME: &str = "ruff"; + +#[cfg(not(target_os = "windows"))] +const TEST_FILTERS: &[(&str, &str)] = &[(".*/resources/test/fixtures/", "[BASEPATH]/")]; +#[cfg(target_os = "windows")] +const TEST_FILTERS: &[(&str, &str)] = &[ + (r".*\\resources\\test\\fixtures\\", "[BASEPATH]\\"), + (r"\\", "/"), +]; + +#[test] +fn check_project_include_defaults() { + // Defaults to checking the current working directory + // + // The test directory includes: + // - A pyproject.toml which specifies an include + // - A nested pyproject.toml which has a Ruff section + // + // The nested project should all be checked instead of respecting the parent includes + + insta::with_settings!({ + filters => TEST_FILTERS.to_vec() + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["check", "--show-files"]).current_dir(Path::new("./resources/test/fixtures/include-test")), @r###" + success: true + exit_code: 0 + ----- stdout ----- + [BASEPATH]/include-test/a.py + [BASEPATH]/include-test/nested-project/e.py + [BASEPATH]/include-test/nested-project/pyproject.toml + [BASEPATH]/include-test/subdirectory/c.py + + ----- stderr ----- + "###); + }); +} + +#[test] +fn check_project_respects_direct_paths() { + // Given a direct path not included in the project `includes`, it should be checked + + insta::with_settings!({ + filters => TEST_FILTERS.to_vec() + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["check", "--show-files", "b.py"]).current_dir(Path::new("./resources/test/fixtures/include-test")), @r###" + success: true + exit_code: 0 + ----- stdout ----- + [BASEPATH]/include-test/b.py + + ----- stderr ----- + "###); + }); +} + +#[test] +fn check_project_respects_subdirectory_includes() { + // Given a direct path to a subdirectory, the include should be respected + + insta::with_settings!({ + filters => TEST_FILTERS.to_vec() + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["check", "--show-files", "subdirectory"]).current_dir(Path::new("./resources/test/fixtures/include-test")), @r###" + success: true + exit_code: 0 + ----- stdout ----- + [BASEPATH]/include-test/subdirectory/c.py + + ----- stderr ----- + "###); + }); +} + +#[test] +fn check_project_from_project_subdirectory_respects_includes() { + // Run from a project subdirectory, the include specified in the parent directory should be respected + + insta::with_settings!({ + filters => TEST_FILTERS.to_vec() + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["check", "--show-files"]).current_dir(Path::new("./resources/test/fixtures/include-test/subdirectory")), @r###" + success: true + exit_code: 0 + ----- stdout ----- + [BASEPATH]/include-test/subdirectory/c.py + + ----- stderr ----- + "###); + }); +} diff --git a/crates/ruff_dev/src/print_ast.rs b/crates/ruff_dev/src/print_ast.rs index eddf8f9d05609..c4ddd97338cb4 100644 --- a/crates/ruff_dev/src/print_ast.rs +++ b/crates/ruff_dev/src/print_ast.rs @@ -1,30 +1,34 @@ //! Print the AST for a given Python file. #![allow(clippy::print_stdout, clippy::print_stderr)] -use std::fs; use std::path::PathBuf; use anyhow::Result; -use ruff_python_parser::{parse, Mode}; + +use ruff_linter::source_kind::SourceKind; +use ruff_python_ast::PySourceType; +use ruff_python_parser::{parse, AsMode}; #[derive(clap::Args)] pub(crate) struct Args { /// Python file for which to generate the AST. #[arg(required = true)] file: PathBuf, - /// Run in Jupyter mode i.e., allow line magics. - #[arg(long)] - jupyter: bool, } pub(crate) fn main(args: &Args) -> Result<()> { - let contents = fs::read_to_string(&args.file)?; - let mode = if args.jupyter { - Mode::Ipython - } else { - Mode::Module - }; - let python_ast = parse(&contents, mode, &args.file.to_string_lossy())?; + let source_type = PySourceType::from(&args.file); + let source_kind = SourceKind::from_path(&args.file, source_type)?.ok_or_else(|| { + anyhow::anyhow!( + "Could not determine source kind for file: {}", + args.file.display() + ) + })?; + let python_ast = parse( + source_kind.source_code(), + source_type.as_mode(), + &args.file.to_string_lossy(), + )?; println!("{python_ast:#?}"); Ok(()) } diff --git a/crates/ruff_dev/src/print_tokens.rs b/crates/ruff_dev/src/print_tokens.rs index 1498ee81a5fd7..a36f9a2c60f49 100644 --- a/crates/ruff_dev/src/print_tokens.rs +++ b/crates/ruff_dev/src/print_tokens.rs @@ -1,30 +1,30 @@ //! Print the token stream for a given Python file. #![allow(clippy::print_stdout, clippy::print_stderr)] -use std::fs; use std::path::PathBuf; use anyhow::Result; -use ruff_python_parser::{lexer, Mode}; + +use ruff_linter::source_kind::SourceKind; +use ruff_python_ast::PySourceType; +use ruff_python_parser::{lexer, AsMode}; #[derive(clap::Args)] pub(crate) struct Args { /// Python file for which to generate the AST. #[arg(required = true)] file: PathBuf, - /// Run in Jupyter mode i.e., allow line magics (`%`, `!`, `?`, `/`, `,`, `;`). - #[arg(long)] - jupyter: bool, } pub(crate) fn main(args: &Args) -> Result<()> { - let contents = fs::read_to_string(&args.file)?; - let mode = if args.jupyter { - Mode::Ipython - } else { - Mode::Module - }; - for (tok, range) in lexer::lex(&contents, mode).flatten() { + let source_type = PySourceType::from(&args.file); + let source_kind = SourceKind::from_path(&args.file, source_type)?.ok_or_else(|| { + anyhow::anyhow!( + "Could not determine source kind for file: {}", + args.file.display() + ) + })?; + for (tok, range) in lexer::lex(source_kind.source_code(), source_type.as_mode()).flatten() { println!( "{start:#?} {tok:#?} {end:#?}", start = range.start(), diff --git a/crates/ruff_diagnostics/src/edit.rs b/crates/ruff_diagnostics/src/edit.rs index 8c05474d21d39..5bd4e629b4c95 100644 --- a/crates/ruff_diagnostics/src/edit.rs +++ b/crates/ruff_diagnostics/src/edit.rs @@ -7,7 +7,7 @@ use ruff_text_size::{Ranged, TextRange, TextSize}; /// A text edit to be applied to a source file. Inserts, deletes, or replaces /// content at a given location. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Edit { /// The start location of the edit. diff --git a/crates/ruff_formatter/src/arguments.rs b/crates/ruff_formatter/src/arguments.rs index 8fa70d73db8d8..d26306c4ea502 100644 --- a/crates/ruff_formatter/src/arguments.rs +++ b/crates/ruff_formatter/src/arguments.rs @@ -1,23 +1,9 @@ use super::{Buffer, Format, Formatter}; use crate::FormatResult; -use std::ffi::c_void; -use std::marker::PhantomData; -/// Mono-morphed type to format an object. Used by the [`crate::format`!], [`crate::format_args`!], and -/// [`crate::write`!] macros. -/// -/// This struct is similar to a dynamic dispatch (using `dyn Format`) because it stores a pointer to the value. -/// However, it doesn't store the pointer to `dyn Format`'s vtable, instead it statically resolves the function -/// pointer of `Format::format` and stores it in `formatter`. +/// A convenience wrapper for representing a formattable argument. pub struct Argument<'fmt, Context> { - /// The value to format stored as a raw pointer where `lifetime` stores the value's lifetime. - value: *const c_void, - - /// Stores the lifetime of the value. To get the most out of our dear borrow checker. - lifetime: PhantomData<&'fmt ()>, - - /// The function pointer to `value`'s `Format::format` method - formatter: fn(*const c_void, &mut Formatter<'_, Context>) -> FormatResult<()>, + value: &'fmt dyn Format, } impl Clone for Argument<'_, Context> { @@ -28,32 +14,19 @@ impl Clone for Argument<'_, Context> { impl Copy for Argument<'_, Context> {} impl<'fmt, Context> Argument<'fmt, Context> { - /// Called by the [ruff_formatter::format_args] macro. Creates a mono-morphed value for formatting - /// an object. + /// Called by the [ruff_formatter::format_args] macro. #[doc(hidden)] #[inline] pub fn new>(value: &'fmt F) -> Self { - #[inline] - fn formatter, Context>( - ptr: *const c_void, - fmt: &mut Formatter, - ) -> FormatResult<()> { - // SAFETY: Safe because the 'fmt lifetime is captured by the 'lifetime' field. - #[allow(unsafe_code)] - F::fmt(unsafe { &*ptr.cast::() }, fmt) - } - - Self { - value: (value as *const F).cast::(), - lifetime: PhantomData, - formatter: formatter::, - } + Self { value } } /// Formats the value stored by this argument using the given formatter. #[inline] + // Seems to only be triggered on wasm32 and looks like a false positive? + #[allow(clippy::trivially_copy_pass_by_ref)] pub(super) fn format(&self, f: &mut Formatter) -> FormatResult<()> { - (self.formatter)(self.value, f) + self.value.fmt(f) } } diff --git a/crates/ruff_formatter/src/builders.rs b/crates/ruff_formatter/src/builders.rs index 7eadba123a207..fdf87e6327daf 100644 --- a/crates/ruff_formatter/src/builders.rs +++ b/crates/ruff_formatter/src/builders.rs @@ -2555,17 +2555,17 @@ pub struct BestFitting<'a, Context> { } impl<'a, Context> BestFitting<'a, Context> { - /// Creates a new best fitting IR with the given variants. The method itself isn't unsafe - /// but it is to discourage people from using it because the printer will panic if - /// the slice doesn't contain at least the least and most expanded variants. + /// Creates a new best fitting IR with the given variants. + /// + /// Callers are required to ensure that the number of variants given + /// is at least 2. /// /// You're looking for a way to create a `BestFitting` object, use the `best_fitting![least_expanded, most_expanded]` macro. /// - /// ## Safety - - /// The slice must contain at least two variants. - #[allow(unsafe_code)] - pub unsafe fn from_arguments_unchecked(variants: Arguments<'a, Context>) -> Self { + /// # Panics + /// + /// When the slice contains less than two variants. + pub fn from_arguments_unchecked(variants: Arguments<'a, Context>) -> Self { assert!( variants.0.len() >= 2, "Requires at least the least expanded and most expanded variants" @@ -2696,14 +2696,12 @@ impl Format for BestFitting<'_, Context> { buffer.write_element(FormatElement::Tag(EndBestFittingEntry)); } - // SAFETY: The constructor guarantees that there are always at least two variants. It's, therefore, - // safe to call into the unsafe `from_vec_unchecked` function - #[allow(unsafe_code)] - let element = unsafe { - FormatElement::BestFitting { - variants: BestFittingVariants::from_vec_unchecked(buffer.into_vec()), - mode: self.mode, - } + // OK because the constructor guarantees that there are always at + // least two variants. + let variants = BestFittingVariants::from_vec_unchecked(buffer.into_vec()); + let element = FormatElement::BestFitting { + variants, + mode: self.mode, }; f.write_element(element); diff --git a/crates/ruff_formatter/src/format_element.rs b/crates/ruff_formatter/src/format_element.rs index f9fe281df3fde..0adcf7dda4338 100644 --- a/crates/ruff_formatter/src/format_element.rs +++ b/crates/ruff_formatter/src/format_element.rs @@ -332,17 +332,14 @@ pub enum BestFittingMode { pub struct BestFittingVariants(Box<[FormatElement]>); impl BestFittingVariants { - /// Creates a new best fitting IR with the given variants. The method itself isn't unsafe - /// but it is to discourage people from using it because the printer will panic if - /// the slice doesn't contain at least the least and most expanded variants. + /// Creates a new best fitting IR with the given variants. /// - /// You're looking for a way to create a `BestFitting` object, use the `best_fitting![least_expanded, most_expanded]` macro. + /// Callers are required to ensure that the number of variants given + /// is at least 2 when using `most_expanded` or `most_flag`. /// - /// ## Safety - /// The slice must contain at least two variants. + /// You're looking for a way to create a `BestFitting` object, use the `best_fitting![least_expanded, most_expanded]` macro. #[doc(hidden)] - #[allow(unsafe_code)] - pub unsafe fn from_vec_unchecked(variants: Vec) -> Self { + pub fn from_vec_unchecked(variants: Vec) -> Self { debug_assert!( variants .iter() @@ -351,12 +348,23 @@ impl BestFittingVariants { >= 2, "Requires at least the least expanded and most expanded variants" ); - Self(variants.into_boxed_slice()) } /// Returns the most expanded variant + /// + /// # Panics + /// + /// When the number of variants is less than two. pub fn most_expanded(&self) -> &[FormatElement] { + assert!( + self.as_slice() + .iter() + .filter(|element| matches!(element, FormatElement::Tag(Tag::StartBestFittingEntry))) + .count() + >= 2, + "Requires at least the least expanded and most expanded variants" + ); self.into_iter().last().unwrap() } @@ -365,7 +373,19 @@ impl BestFittingVariants { } /// Returns the least expanded variant + /// + /// # Panics + /// + /// When the number of variants is less than two. pub fn most_flat(&self) -> &[FormatElement] { + assert!( + self.as_slice() + .iter() + .filter(|element| matches!(element, FormatElement::Tag(Tag::StartBestFittingEntry))) + .count() + >= 2, + "Requires at least the least expanded and most expanded variants" + ); self.into_iter().next().unwrap() } } diff --git a/crates/ruff_formatter/src/macros.rs b/crates/ruff_formatter/src/macros.rs index 97a4cc696115d..2e327739a9091 100644 --- a/crates/ruff_formatter/src/macros.rs +++ b/crates/ruff_formatter/src/macros.rs @@ -329,10 +329,8 @@ macro_rules! format { #[macro_export] macro_rules! best_fitting { ($least_expanded:expr, $($tail:expr),+ $(,)?) => {{ - #[allow(unsafe_code)] - unsafe { - $crate::BestFitting::from_arguments_unchecked($crate::format_args!($least_expanded, $($tail),+)) - } + // OK because the macro syntax requires at least two variants. + $crate::BestFitting::from_arguments_unchecked($crate::format_args!($least_expanded, $($tail),+)) }} } diff --git a/crates/ruff_linter/Cargo.toml b/crates/ruff_linter/Cargo.toml index 6f129984ffb8b..ea1cb6570b57b 100644 --- a/crates/ruff_linter/Cargo.toml +++ b/crates/ruff_linter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff_linter" -version = "0.1.6" +version = "0.1.8" publish = false authors = { workspace = true } edition = { workspace = true } @@ -71,6 +71,7 @@ toml = { workspace = true } typed-arena = { version = "2.0.2" } unicode-width = { workspace = true } unicode_names2 = { workspace = true } +url = { version = "2.2.2" } wsl = { version = "0.1.0" } [dev-dependencies] diff --git a/crates/ruff_linter/resources/test/fixtures/control-flow-graph/for.py b/crates/ruff_linter/resources/test/fixtures/control-flow-graph/for.py index a5807a635a412..9aef74d5d027f 100644 --- a/crates/ruff_linter/resources/test/fixtures/control-flow-graph/for.py +++ b/crates/ruff_linter/resources/test/fixtures/control-flow-graph/for.py @@ -39,3 +39,18 @@ def func(): for i in range(1110): if True: break + +# TODO(charlie): The `pass` here does not get properly redirected to the top of the +# loop, unlike below. +def func(): + for i in range(5): + pass + else: + return 1 + +def func(): + for i in range(5): + pass + else: + return 1 + x = 1 diff --git a/crates/ruff_linter/resources/test/fixtures/control-flow-graph/match.py b/crates/ruff_linter/resources/test/fixtures/control-flow-graph/match.py index cce019e3085e9..d83726268991f 100644 --- a/crates/ruff_linter/resources/test/fixtures/control-flow-graph/match.py +++ b/crates/ruff_linter/resources/test/fixtures/control-flow-graph/match.py @@ -129,3 +129,11 @@ class Color(Enum): print("Grass is green") case Color.BLUE: print("I'm feeling the blues :(") + + +def func(point): + match point: + case (0, 0): + print("Origin") + case foo: + raise ValueError("oops") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_annotations/auto_return_type.py b/crates/ruff_linter/resources/test/fixtures/flake8_annotations/auto_return_type.py index b7d58a6f94302..60d89cbec5cdc 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_annotations/auto_return_type.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_annotations/auto_return_type.py @@ -30,3 +30,155 @@ def func(x: int): def func(x: int): return 1 + 2.5 if x > 0 else 1.5 or "str" + + +def func(x: int): + if not x: + return None + return {"foo": 1} + + +def func(x: int): + return {"foo": 1} + + +def func(x: int): + if not x: + return 1 + else: + return True + + +def func(x: int): + if not x: + return 1 + else: + return None + + +def func(x: int): + if not x: + return 1 + elif x > 5: + return "str" + else: + return None + + +def func(x: int): + if x: + return 1 + + +def func(): + x = 1 + + +def func(x: int): + if x > 0: + return 1 + + +def func(x: int): + match x: + case [1, 2, 3]: + return 1 + case 4 as y: + return "foo" + + +def func(x: int): + for i in range(5): + if i > 0: + return 1 + + +def func(x: int): + for i in range(5): + if i > 0: + return 1 + else: + return 4 + + +def func(x: int): + for i in range(5): + if i > 0: + break + else: + return 4 + + +def func(x: int): + try: + pass + except: + return 1 + + +def func(x: int): + try: + pass + except: + return 1 + finally: + return 2 + + +def func(x: int): + try: + pass + except: + return 1 + else: + return 2 + + +def func(x: int): + try: + return 1 + except: + return 2 + else: + pass + + +def func(x: int): + while x > 0: + break + return 1 + + +import abc +from abc import abstractmethod + + +class Foo(abc.ABC): + @abstractmethod + def method(self): + pass + + @abc.abstractmethod + def method(self): + """Docstring.""" + + @abc.abstractmethod + def method(self): + ... + + @staticmethod + @abstractmethod + def method(): + pass + + @classmethod + @abstractmethod + def method(cls): + pass + + @abstractmethod + def method(self): + if self.x > 0: + return 1 + else: + return 1.5 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S104.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S104.py index 3bbab01871247..7e50db007619c 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S104.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S104.py @@ -8,6 +8,7 @@ def func(address): # Error "0.0.0.0" '0.0.0.0' +f"0.0.0.0" # Error diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S108.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S108.py index 1689af66e63c5..c7cc7dd4809f5 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S108.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S108.py @@ -5,6 +5,9 @@ with open("/tmp/abc", "w") as f: f.write("def") +with open(f"/tmp/abc", "w") as f: + f.write("def") + with open("/var/tmp/123", "w") as f: f.write("def") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S202.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S202.py new file mode 100644 index 0000000000000..bba1deda4ab36 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S202.py @@ -0,0 +1,65 @@ +import sys +import tarfile +import tempfile + + +def unsafe_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp()) + tar.close() + + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + tar.close() + + +def list_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=[]) + tar.close() + + +def provided_members_archive_handler(filename): + tar = tarfile.open(filename) + tarfile.extractall(path=tempfile.mkdtemp(), members=tar) + tar.close() + + +def filter_data(filename): + tar = tarfile.open(filename) + tarfile.extractall(path=tempfile.mkdtemp(), filter="data") + tar.close() + + +def filter_fully_trusted(filename): + tar = tarfile.open(filename) + tarfile.extractall(path=tempfile.mkdtemp(), filter="fully_trusted") + tar.close() + + +def filter_tar(filename): + tar = tarfile.open(filename) + tarfile.extractall(path=tempfile.mkdtemp(), filter="tar") + tar.close() + + +def members_filter(tarfile): + result = [] + for member in tarfile.getmembers(): + if '../' in member.name: + print('Member name container directory traversal sequence') + continue + elif (member.issym() or member.islnk()) and ('../' in member.linkname): + print('Symlink to external resource') + continue + result.append(member) + return result + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + unsafe_archive_handler(filename) + managed_members_archive_handler(filename) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S611.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S611.py new file mode 100644 index 0000000000000..ee4230273582f --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S611.py @@ -0,0 +1,13 @@ +from django.db.models.expressions import RawSQL +from django.contrib.auth.models import User + +User.objects.annotate(val=RawSQL('secure', [])) +User.objects.annotate(val=RawSQL('%secure' % 'nos', [])) +User.objects.annotate(val=RawSQL('{}secure'.format('no'), [])) +raw = '"username") AS "val" FROM "auth_user" WHERE "username"="admin" --' +User.objects.annotate(val=RawSQL(raw, [])) +raw = '"username") AS "val" FROM "auth_user"' \ + ' WHERE "username"="admin" OR 1=%s --' +User.objects.annotate(val=RawSQL(raw, [0])) +User.objects.annotate(val=RawSQL(sql='{}secure'.format('no'), params=[])) +User.objects.annotate(val=RawSQL(params=[], sql='{}secure'.format('no'))) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_boolean_trap/FBT.py b/crates/ruff_linter/resources/test/fixtures/flake8_boolean_trap/FBT.py index 58dcb4b5164b5..2c48a7d629fda 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_boolean_trap/FBT.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_boolean_trap/FBT.py @@ -106,3 +106,11 @@ def func(x: bool | str): def func(x: int | str): pass + + +from typing import override + + +@override +def func(x: bool): + pass diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B015.ipynb b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B015.ipynb new file mode 100644 index 0000000000000..1a1446b60d54c --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B015.ipynb @@ -0,0 +1,149 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "33faf7ad-a3fd-4ac4-a0c3-52e507ed49df", + "metadata": {}, + "outputs": [], + "source": [ + "x = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "481fb4bf-c1b9-47da-927f-3cfdfe4b49ec", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Simple case\n", + "x == 1" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "2f0c65a5-0a0e-4080-afce-5a8ed0d706df", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Only skip the last expression\n", + "x == 1 # B018\n", + "x == 1" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "5a3fd75d-26d9-44f7-b013-1684aabfd0ae", + "metadata": {}, + "outputs": [], + "source": [ + "# Nested expressions isn't relevant\n", + "if True:\n", + " x == 1" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e00e1afa-b76c-4774-be2a-7223641579e4", + "metadata": {}, + "outputs": [], + "source": [ + "# Semicolons shouldn't affect the output\n", + "x == 1;" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "05eab5b9-e2ba-4954-8ef3-b035a79573fe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Semicolons with multiple expressions\n", + "x == 1; x == 1" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "9cbbddc5-83fc-4fdb-81ab-53a3912ae898", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Comments, newlines and whitespace\n", + "x == 1 # comment\n", + "\n", + "# another comment" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (ruff-playground)", + "language": "python", + "name": "ruff-playground" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B018.ipynb b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B018.ipynb new file mode 100644 index 0000000000000..35c501611c89f --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B018.ipynb @@ -0,0 +1,149 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "33faf7ad-a3fd-4ac4-a0c3-52e507ed49df", + "metadata": {}, + "outputs": [], + "source": [ + "x = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "481fb4bf-c1b9-47da-927f-3cfdfe4b49ec", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Simple case\n", + "x" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "2f0c65a5-0a0e-4080-afce-5a8ed0d706df", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Only skip the last expression\n", + "x # B018\n", + "x" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "5a3fd75d-26d9-44f7-b013-1684aabfd0ae", + "metadata": {}, + "outputs": [], + "source": [ + "# Nested expressions isn't relevant\n", + "if True:\n", + " x" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e00e1afa-b76c-4774-be2a-7223641579e4", + "metadata": {}, + "outputs": [], + "source": [ + "# Semicolons shouldn't affect the output\n", + "x;" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "05eab5b9-e2ba-4954-8ef3-b035a79573fe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Semicolons with multiple expressions\n", + "x; x" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "9cbbddc5-83fc-4fdb-81ab-53a3912ae898", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Comments, newlines and whitespace\n", + "x # comment\n", + "\n", + "# another comment" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (ruff-playground)", + "language": "python", + "name": "ruff-playground" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_django/DJ012.py b/crates/ruff_linter/resources/test/fixtures/flake8_django/DJ012.py index a0f8d9da221a0..20d3e4078ba96 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_django/DJ012.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_django/DJ012.py @@ -127,3 +127,21 @@ def get_absolute_url(self): pass middle_name = models.CharField(max_length=32) + + +class BaseModel(models.Model): + pass + + +class StrBeforeFieldInheritedModel(BaseModel): + """Model with `__str__` before fields.""" + + class Meta: + verbose_name = "test" + verbose_name_plural = "tests" + + def __str__(self): + return "foobar" + + first_name = models.CharField(max_length=32) + diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_errmsg/EM.py b/crates/ruff_linter/resources/test/fixtures/flake8_errmsg/EM.py index 01e53ac3ddedd..fbf6eb464aa24 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_errmsg/EM.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_errmsg/EM.py @@ -27,7 +27,7 @@ def f_ok(): raise RuntimeError(msg) -def f_unfixable(): +def f_msg_defined(): msg = "hello" raise RuntimeError("This is an example exception") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE796.py b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE796.py index 227ae8acc27b0..585e38b4d1b0c 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE796.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE796.py @@ -64,3 +64,9 @@ class FakeEnum10(enum.Enum): A = enum.auto() B = enum.auto() C = enum.auto() + + +class FakeEnum10(enum.Enum): + A = ... + B = ... # PIE796 + C = ... # PIE796 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE796.pyi b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE796.pyi new file mode 100644 index 0000000000000..ccfb75a2846a6 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE796.pyi @@ -0,0 +1,7 @@ +import enum + + +class FakeEnum1(enum.Enum): + A = ... + B = ... + C = ... diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE804.py b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE804.py index 84274c853a8aa..a5b3674422e1a 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE804.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE804.py @@ -10,7 +10,6 @@ foo(**{}) - foo(**{**data, "foo": "buzz"}) foo(**buzz) foo(**{"bar-foo": True}) @@ -20,3 +19,8 @@ foo(**{"": True}) foo(**{f"buzz__{bar}": True}) abc(**{"for": 3}) +foo(**{},) + +# Duplicated key names won't be fixed, to avoid syntax errors. +abc(**{'a': b}, **{'a': c}) # PIE804 +abc(a=1, **{'a': c}, **{'b': c}) # PIE804 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI030.py b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI030.py index 3c9d0ac15c9c3..c6cd2b453707a 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI030.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI030.py @@ -36,3 +36,54 @@ def func2() -> Literal[1] | Literal[2]: # Error # Should emit for union in generic parent type. field11: dict[Literal[1] | Literal[2], str] # Error + +# Should emit for unions with more than two cases +field12: Literal[1] | Literal[2] | Literal[3] # Error +field13: Literal[1] | Literal[2] | Literal[3] | Literal[4] # Error + +# Should emit for unions with more than two cases, even if not directly adjacent +field14: Literal[1] | Literal[2] | str | Literal[3] # Error + +# Should emit for unions with mixed literal internal types +field15: Literal[1] | Literal["foo"] | Literal[True] # Error + +# Shouldn't emit for duplicate field types with same value; covered by Y016 +field16: Literal[1] | Literal[1] # OK + +# Shouldn't emit if in new parent type +field17: Literal[1] | dict[Literal[2], str] # OK + +# Shouldn't emit if not in a union parent +field18: dict[Literal[1], Literal[2]] # OK + +# Should respect name of literal type used +field19: typing.Literal[1] | typing.Literal[2] # Error + +# Should emit in cases with newlines +field20: typing.Union[ + Literal[ + 1 # test + ], + Literal[2], +] # Error, newline and comment will not be emitted in message + +# Should handle multiple unions with multiple members +field21: Literal[1, 2] | Literal[3, 4] # Error + +# Should emit in cases with `typing.Union` instead of `|` +field22: typing.Union[Literal[1], Literal[2]] # Error + +# Should emit in cases with `typing_extensions.Literal` +field23: typing_extensions.Literal[1] | typing_extensions.Literal[2] # Error + +# Should emit in cases with nested `typing.Union` +field24: typing.Union[Literal[1], typing.Union[Literal[2], str]] # Error + +# Should emit in cases with mixed `typing.Union` and `|` +field25: typing.Union[Literal[1], Literal[2] | str] # Error + +# Should emit only once in cases with multiple nested `typing.Union` +field24: typing.Union[Literal[1], typing.Union[Literal[2], typing.Union[Literal[3], Literal[4]]]] # Error + +# Should use the first literal subscript attribute when fixing +field25: typing.Union[typing_extensions.Literal[1], typing.Union[Literal[2], typing.Union[Literal[3], Literal[4]]], str] # Error diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI030.pyi b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI030.pyi index e92af925df67d..c6cd2b453707a 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI030.pyi +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI030.pyi @@ -84,3 +84,6 @@ field25: typing.Union[Literal[1], Literal[2] | str] # Error # Should emit only once in cases with multiple nested `typing.Union` field24: typing.Union[Literal[1], typing.Union[Literal[2], typing.Union[Literal[3], Literal[4]]]] # Error + +# Should use the first literal subscript attribute when fixing +field25: typing.Union[typing_extensions.Literal[1], typing.Union[Literal[2], typing.Union[Literal[3], Literal[4]]], str] # Error diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI042.py b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI042.py index 2936c39c6c836..2d2b932e42c8a 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI042.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI042.py @@ -22,3 +22,7 @@ # check that this edge case doesn't crash _: TypeAlias = str | int + +# PEP 695 +type foo_bar = int | str +type FooBar = int | str diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI042.pyi b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI042.pyi index 2936c39c6c836..2d2b932e42c8a 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI042.pyi +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI042.pyi @@ -22,3 +22,7 @@ Snake_case_alias: TypeAlias = int | float # PYI042, since not camel case # check that this edge case doesn't crash _: TypeAlias = str | int + +# PEP 695 +type foo_bar = int | str +type FooBar = int | str diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI043.py b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI043.py index b48f5e0fa8c47..b8107662f9931 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI043.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI043.py @@ -21,3 +21,7 @@ # check that this edge case doesn't crash _: TypeAlias = str | int + +# PEP 695 +type _FooT = str | int +type Foo = str | int diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI043.pyi b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI043.pyi index b48f5e0fa8c47..b8107662f9931 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI043.pyi +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI043.pyi @@ -21,3 +21,7 @@ _PrivateAliasS2: TypeAlias = Annotated[str, "also okay"] # check that this edge case doesn't crash _: TypeAlias = str | int + +# PEP 695 +type _FooT = str | int +type Foo = str | int diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI050.pyi b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI050.pyi index 4720ee7756b6a..583c96e71b59b 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI050.pyi +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI050.pyi @@ -10,3 +10,14 @@ def foo_no_return_typing_extensions( def foo_no_return_kwarg(arg: int, *, arg2: NoReturn): ... # Error: PYI050 def foo_no_return_pos_only(arg: int, /, arg2: NoReturn): ... # Error: PYI050 def foo_never(arg: Never): ... +def foo_args(*args: NoReturn): ... # Error: PYI050 +def foo_kwargs(**kwargs: NoReturn): ... # Error: PYI050 +def foo_args_kwargs(*args: NoReturn, **kwargs: NoReturn): ... # Error: PYI050 +def foo_int_args(*args: int): ... +def foo_int_kwargs(**kwargs: int): ... +def foo_int_args_kwargs(*args: int, **kwargs: int): ... +def foo_int_args_no_return(*args: int, **kwargs: NoReturn): ... # Error: PYI050 +def foo_int_kwargs_no_return(*args: NoReturn, **kwargs: int): ... # Error: PYI050 +def foo_args_never(*args: Never): ... +def foo_kwargs_never(**kwargs: Never): ... +def foo_args_kwargs_never(*args: Never, **kwargs: Never): ... diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI053.py b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI053.py index 8b2811eb63467..640d1fb42b87c 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI053.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI053.py @@ -32,6 +32,7 @@ def f8(x: bytes = b"50 character byte stringgggggggggggggggggggggggggg\xff") -> foo: str = "50 character stringggggggggggggggggggggggggggggggg" bar: str = "51 character stringgggggggggggggggggggggggggggggggg" +baz: str = f"51 character stringgggggggggggggggggggggggggggggggg" baz: bytes = b"50 character byte stringgggggggggggggggggggggggggg" diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI053.pyi b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI053.pyi index 71064d9bdbd02..e87388ec9acbb 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI053.pyi +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI053.pyi @@ -29,6 +29,10 @@ baz: bytes = b"50 character byte stringgggggggggggggggggggggggggg" # OK qux: bytes = b"51 character byte stringggggggggggggggggggggggggggg\xff" # Error: PYI053 +ffoo: str = f"50 character stringggggggggggggggggggggggggggggggg" # OK + +fbar: str = f"51 character stringgggggggggggggggggggggggggggggggg" # Error: PYI053 + class Demo: """Docstrings are excluded from this rule. Some padding.""" # OK diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_raise/RSE102.py b/crates/ruff_linter/resources/test/fixtures/flake8_raise/RSE102.py index 0a750b97cb190..bba0e98b17caf 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_raise/RSE102.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_raise/RSE102.py @@ -82,3 +82,14 @@ def error(): # RSE102 raise Foo() + +# OK +raise ctypes.WinError() + + +def func(): + pass + + +# OK +raise func() diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM117.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM117.py index c3c64044a2aac..43c8c8a12b4ab 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM117.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM117.py @@ -134,3 +134,32 @@ def method1(self) -> T: f" something { my_dict["key"] } something else " f"foo {f"bar {x}"} baz" + +# Allow cascading for some statements. +import anyio +import asyncio +import trio + +async with asyncio.timeout(1): + async with A() as a: + pass + +async with A(): + async with asyncio.timeout(1): + pass + +async with asyncio.timeout(1): + async with asyncio.timeout_at(1): + async with anyio.CancelScope(): + async with anyio.fail_after(1): + async with anyio.move_on_after(1): + async with trio.fail_after(1): + async with trio.fail_at(1): + async with trio.move_on_after(1): + async with trio.move_on_at(1): + pass + +# Do not supress combination, if a context manager is already combined with another. +async with asyncio.timeout(1), A(): + async with B(): + pass diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_trio/TRIO115.py b/crates/ruff_linter/resources/test/fixtures/flake8_trio/TRIO115.py index 410408576acc6..764b5c1d6e9f5 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_trio/TRIO115.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_trio/TRIO115.py @@ -19,12 +19,48 @@ async def func(): bar = "bar" trio.sleep(bar) + x, y = 0, 2000 + trio.sleep(x) # TRIO115 + trio.sleep(y) # OK + + (a, b, [c, (d, e)]) = (1, 2, (0, [4, 0])) + trio.sleep(c) # TRIO115 + trio.sleep(d) # OK + trio.sleep(e) # TRIO115 + + m_x, m_y = 0 + trio.sleep(m_y) # OK + trio.sleep(m_x) # OK + + m_a = m_b = 0 + trio.sleep(m_a) # TRIO115 + trio.sleep(m_b) # TRIO115 + + m_c = (m_d, m_e) = (0, 0) + trio.sleep(m_c) # OK + trio.sleep(m_d) # TRIO115 + trio.sleep(m_e) # TRIO115 + def func(): + import trio + trio.run(trio.sleep(0)) # TRIO115 from trio import Event, sleep + def func(): sleep(0) # TRIO115 + + +async def func(): + await sleep(seconds=0) # TRIO115 + + +def func(): + import trio + + if (walrus := 0) == 0: + trio.sleep(walrus) # TRIO115 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/quote.py b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/quote.py new file mode 100644 index 0000000000000..de3d609d07444 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/quote.py @@ -0,0 +1,89 @@ +def f(): + from pandas import DataFrame + + def baz() -> DataFrame: + ... + + +def f(): + from pandas import DataFrame + + def baz() -> DataFrame[int]: + ... + + +def f(): + from pandas import DataFrame + + def baz() -> DataFrame["int"]: + ... + + +def f(): + import pandas as pd + + def baz() -> pd.DataFrame: + ... + + +def f(): + import pandas as pd + + def baz() -> pd.DataFrame.Extra: + ... + + +def f(): + import pandas as pd + + def baz() -> pd.DataFrame | int: + ... + + + +def f(): + from pandas import DataFrame + + def baz() -> DataFrame(): + ... + + +def f(): + from typing import Literal + + from pandas import DataFrame + + def baz() -> DataFrame[Literal["int"]]: + ... + + +def f(): + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from pandas import DataFrame + + def func(value: DataFrame): + ... + + +def f(): + from pandas import DataFrame, Series + + def baz() -> DataFrame | Series: + ... + + +def f(): + from pandas import DataFrame, Series + + def baz() -> ( + DataFrame | + Series + ): + ... + + class C: + x: DataFrame[ + int + ] = 1 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/singledispatch.py b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/singledispatch.py new file mode 100644 index 0000000000000..a519a58b4f15b --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/singledispatch.py @@ -0,0 +1,34 @@ +"""Test module.""" +from __future__ import annotations + +from functools import singledispatch +from typing import TYPE_CHECKING + +from numpy import asarray +from numpy.typing import ArrayLike +from scipy.sparse import spmatrix +from pandas import DataFrame + +if TYPE_CHECKING: + from numpy import ndarray + + +@singledispatch +def to_array_or_mat(a: ArrayLike | spmatrix) -> ndarray | spmatrix: + """Convert arg to array or leaves it as sparse matrix.""" + msg = f"Unhandled type {type(a)}" + raise NotImplementedError(msg) + + +@to_array_or_mat.register +def _(a: ArrayLike) -> ndarray: + return asarray(a) + + +@to_array_or_mat.register +def _(a: spmatrix) -> spmatrix: + return a + + +def _(a: DataFrame) -> DataFrame: + return a diff --git a/crates/ruff_linter/resources/test/fixtures/isort/force_sort_within_sections_future.py b/crates/ruff_linter/resources/test/fixtures/isort/force_sort_within_sections_future.py new file mode 100644 index 0000000000000..3698d72a9c55e --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/force_sort_within_sections_future.py @@ -0,0 +1,2 @@ +import __future__ +from __future__ import annotations diff --git a/crates/ruff_linter/resources/test/fixtures/isort/force_sort_within_sections_lines_between.py b/crates/ruff_linter/resources/test/fixtures/isort/force_sort_within_sections_lines_between.py new file mode 100644 index 0000000000000..5459d78bfd12f --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/force_sort_within_sections_lines_between.py @@ -0,0 +1,4 @@ +from a import x +import b +from c import y +import d diff --git a/crates/ruff_linter/resources/test/fixtures/isort/from_first.py b/crates/ruff_linter/resources/test/fixtures/isort/from_first.py new file mode 100644 index 0000000000000..a15a573d28215 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/from_first.py @@ -0,0 +1,5 @@ +from __future__ import blah + +from os import path + +import os diff --git a/crates/ruff_linter/resources/test/fixtures/isort/future_from.py b/crates/ruff_linter/resources/test/fixtures/isort/future_from.py new file mode 100644 index 0000000000000..3698d72a9c55e --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/future_from.py @@ -0,0 +1,2 @@ +import __future__ +from __future__ import annotations diff --git a/crates/ruff_linter/resources/test/fixtures/isort/length_sort_from_imports.py b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_from_imports.py new file mode 100644 index 0000000000000..bf6a5732d2236 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_from_imports.py @@ -0,0 +1,3 @@ +from mediuuuuuuuuuuum import a +from short import b +from loooooooooooooooooooooog import c diff --git a/crates/ruff_linter/resources/test/fixtures/isort/length_sort_non_ascii_members.py b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_non_ascii_members.py new file mode 100644 index 0000000000000..6419d6251196c --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_non_ascii_members.py @@ -0,0 +1,11 @@ +from module1 import ( + loooooooooooooong, + σηορτ, + mediuuuuum, + shoort, + looooooooooooooong, + μεδιυυυυυμ, + short, + mediuuuuuum, + λοοοοοοοοοοοοοονγ, +) diff --git a/crates/ruff_linter/resources/test/fixtures/isort/length_sort_non_ascii_modules.py b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_non_ascii_modules.py new file mode 100644 index 0000000000000..e7895a0d2becb --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_non_ascii_modules.py @@ -0,0 +1,9 @@ +import loooooooooooooong +import mediuuuuuum +import short +import σηορτ +import shoort +import mediuuuuum +import λοοοοοοοοοοοοοονγ +import μεδιυυυυυμ +import looooooooooooooong diff --git a/crates/ruff_linter/resources/test/fixtures/isort/length_sort_straight_and_from_imports.py b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_straight_and_from_imports.py new file mode 100644 index 0000000000000..738efb3549339 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_straight_and_from_imports.py @@ -0,0 +1,6 @@ +import mediuuuuuum +import short +import looooooooooooooooong +from looooooooooooooong import a +from mediuuuum import c +from short import b diff --git a/crates/ruff_linter/resources/test/fixtures/isort/length_sort_straight_imports.py b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_straight_imports.py new file mode 100644 index 0000000000000..70aabd043b021 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_straight_imports.py @@ -0,0 +1,4 @@ +import mediuuuuuumb +import short +import looooooooooooooooong +import mediuuuuuuma diff --git a/crates/ruff_linter/resources/test/fixtures/isort/length_sort_with_relative_imports.py b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_with_relative_imports.py new file mode 100644 index 0000000000000..ca0b97065ecad --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_with_relative_imports.py @@ -0,0 +1,7 @@ +from ..looooooooooooooong import a +from ...mediuuuum import b +from .short import c +from ....short import c +from . import d +from .mediuuuum import a +from ......short import b diff --git a/crates/ruff_linter/resources/test/fixtures/isort/length_sort_with_star_import.py b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_with_star_import.py new file mode 100644 index 0000000000000..3dbf73c4d2974 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/length_sort_with_star_import.py @@ -0,0 +1,3 @@ +from looooooooooooooong import a +from mediuuuum import * +from short import * diff --git a/crates/ruff_linter/resources/test/fixtures/isort/main_first_party.py b/crates/ruff_linter/resources/test/fixtures/isort/main_first_party.py new file mode 100644 index 0000000000000..ba224527c3b9a --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/main_first_party.py @@ -0,0 +1,11 @@ +import os + +import __main__ +import third_party + +import first_party + +os.a +third_party.a +__main__.a +first_party.a diff --git a/crates/ruff_linter/resources/test/fixtures/pep8_naming/N806.py b/crates/ruff_linter/resources/test/fixtures/pep8_naming/N806.py index 0a9a95954c73c..80114331302d5 100644 --- a/crates/ruff_linter/resources/test/fixtures/pep8_naming/N806.py +++ b/crates/ruff_linter/resources/test/fixtures/pep8_naming/N806.py @@ -1,6 +1,6 @@ import collections from collections import namedtuple -from typing import TypeAlias, TypeVar, NewType, NamedTuple, TypedDict +from typing import Type, TypeAlias, TypeVar, NewType, NamedTuple, TypedDict GLOBAL: str = "foo" @@ -25,6 +25,8 @@ def assign(): IntOrStr: TypeAlias = int | str + type MyInt = int + def aug_assign(rank, world_size): global CURRENT_PORT @@ -38,3 +40,21 @@ def loop_assign(): global CURRENT_PORT for CURRENT_PORT in range(5): pass + + +def model_assign() -> None: + Bad = apps.get_model("zerver", "Stream") # N806 + Attachment = apps.get_model("zerver", "Attachment") # OK + Recipient = apps.get_model("zerver", model_name="Recipient") # OK + Address: Type = apps.get_model("zerver", "Address") # OK + + from django.utils.module_loading import import_string + + Bad = import_string("django.core.exceptions.ValidationError") # N806 + ValidationError = import_string("django.core.exceptions.ValidationError") # OK + + Bad = apps.get_model() # N806 + Bad = apps.get_model(model_name="Stream") # N806 + + Address: Type = apps.get_model("zerver", variable) # OK + ValidationError = import_string(variable) # N806 diff --git a/crates/ruff_linter/resources/test/fixtures/perflint/PERF101.py b/crates/ruff_linter/resources/test/fixtures/perflint/PERF101.py index 6123e6d6526bf..e6ae0b8f25d75 100644 --- a/crates/ruff_linter/resources/test/fixtures/perflint/PERF101.py +++ b/crates/ruff_linter/resources/test/fixtures/perflint/PERF101.py @@ -50,3 +50,21 @@ for i in itertools.product(foo_int): # Ok pass + +for i in list(foo_list): # Ok + foo_list.append(i + 1) + +for i in list(foo_list): # PERF101 + # Make sure we match the correct list + other_list.append(i + 1) + +for i in list(foo_tuple): # Ok + foo_tuple.append(i + 1) + +for i in list(foo_set): # Ok + foo_set.append(i + 1) + +x, y, nested_tuple = (1, 2, (3, 4, 5)) + +for i in list(nested_tuple): # PERF101 + pass diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E20.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E20.py index 84355d21e0e48..7c76aa6ed14b0 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E20.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E20.py @@ -135,3 +135,15 @@ #: E203:1:20 ham[{lower + offset : upper + offset} : upper + offset] + +#: Okay +ham[upper:] + +#: Okay +ham[upper :] + +#: E202:1:12 +ham[upper : ] + +#: E203:1:10 +ham[upper :] diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E26.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E26.py index 9d35553dc521a..052baafcab781 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E26.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E26.py @@ -72,3 +72,15 @@ def oof(): # EF Means test is giving error and Failing #! Means test is segfaulting # 8 Means test runs forever + +#: Colon prefix is okay + +###This is a variable ### + +# We should strip the space, but preserve the hashes. +#: E266:1:3 +## Foo + +a = 1 ## Foo + +a = 1 #:Foo diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E27.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E27.py index 576e43ae01300..7fb6fbb4f021b 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E27.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E27.py @@ -60,3 +60,6 @@ def f(): if (a and b): pass +#: Okay +def f(): + return 1 diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E402.ipynb b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E402.ipynb new file mode 100644 index 0000000000000..9f9579e77e5dd --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E402.ipynb @@ -0,0 +1,113 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "33faf7ad-a3fd-4ac4-a0c3-52e507ed49df", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "sys.path" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1331140f-2741-4661-9086-0764368710c9", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4113383-725d-4f04-80b8-a3080b2b8c4b", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "os.path\n", + "\n", + "import pathlib" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5d2ef63-ae60-4311-bae3-42e845afba3f", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "79599475-a5ee-4f60-80d1-6efa77693da0", + "metadata": {}, + "outputs": [], + "source": [ + "import a\n", + "\n", + "try:\n", + " import b\n", + "except ImportError:\n", + " pass\n", + "else:\n", + " pass\n", + "\n", + "__some__magic = 1\n", + "\n", + "import c" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "863dcc35-5c8d-4d05-8b4a-91059e944112", + "metadata": {}, + "outputs": [], + "source": [ + "import ok\n", + "\n", + "\n", + "def foo() -> None:\n", + " import e\n", + "\n", + "\n", + "import no_ok" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b2377d0-b814-4057-83ec-d443d8e19401", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (ruff-playground)", + "language": "python", + "name": "ruff-playground" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E402.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E402.py index d5943407852a2..fdd0e32ee29f8 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E402.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E402.py @@ -19,21 +19,32 @@ else: import e -__some__magic = 1 +import sys +sys.path.insert(0, "some/path") import f +import matplotlib + +matplotlib.use("Agg") + +import g + +__some__magic = 1 + +import h + def foo() -> None: - import e + import i if __name__ == "__main__": - import g + import j -import h; import i +import k; import l if __name__ == "__main__": - import j; \ -import k + import m; \ +import n diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E703.ipynb b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E703.ipynb new file mode 100644 index 0000000000000..97606b62f3792 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E703.ipynb @@ -0,0 +1,94 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "33faf7ad-a3fd-4ac4-a0c3-52e507ed49df", + "metadata": {}, + "outputs": [], + "source": [ + "x = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "481fb4bf-c1b9-47da-927f-3cfdfe4b49ec", + "metadata": {}, + "outputs": [], + "source": [ + "# Simple case\n", + "x;" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "2f0c65a5-0a0e-4080-afce-5a8ed0d706df", + "metadata": {}, + "outputs": [], + "source": [ + "# Only skip the last expression\n", + "x; # E703\n", + "x;" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "5a3fd75d-26d9-44f7-b013-1684aabfd0ae", + "metadata": {}, + "outputs": [], + "source": [ + "# Nested expressions isn't relevant\n", + "if True:\n", + " x;" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "05eab5b9-e2ba-4954-8ef3-b035a79573fe", + "metadata": {}, + "outputs": [], + "source": [ + "# Semicolons with multiple expressions\n", + "x; x;" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "9cbbddc5-83fc-4fdb-81ab-53a3912ae898", + "metadata": {}, + "outputs": [], + "source": [ + "# Comments, newlines and whitespace\n", + "x; # comment\n", + "\n", + "# another comment" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (ruff-playground)", + "language": "python", + "name": "ruff-playground" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_0.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_0.py index 967ed5bc4d334..85ec535e22d19 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_0.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_0.py @@ -43,3 +43,6 @@ def f(): ''' # noqa regex = '\\\_' + +#: W605:1:7 +u'foo\ bar' diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py index 20bf0ea14c8f7..b34ad587c46d5 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py @@ -1,40 +1,54 @@ +# Same as `W605_0.py` but using f-strings instead. + #: W605:1:10 -regex = '\.png$' +regex = f'\.png$' #: W605:2:1 -regex = ''' +regex = f''' \.png$ ''' #: W605:2:6 f( - '\_' + f'\_' ) #: W605:4:6 -""" +f""" multi-line literal with \_ somewhere in the middle """ +#: W605:1:38 +value = f'new line\nand invalid escape \_ here' -def f(): - #: W605:1:11 - return'\.png$' #: Okay -regex = r'\.png$' -regex = '\\.png$' -regex = r''' +regex = fr'\.png$' +regex = f'\\.png$' +regex = fr''' \.png$ ''' -regex = r''' +regex = fr''' \\.png$ ''' -s = '\\' -regex = '\w' # noqa -regex = ''' +s = f'\\' +regex = f'\w' # noqa +regex = f''' \w ''' # noqa + +regex = f'\\\_' +value = f'\{{1}}' +value = f'\{1}' +value = f'{1:\}' +value = f"{f"\{1}"}" +value = rf"{f"\{1}"}" + +# Okay +value = rf'\{{1}}' +value = rf'\{1}' +value = rf'{1:\}' +value = f"{rf"\{1}"}" diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_2.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_2.py deleted file mode 100644 index b34ad587c46d5..0000000000000 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_2.py +++ /dev/null @@ -1,54 +0,0 @@ -# Same as `W605_0.py` but using f-strings instead. - -#: W605:1:10 -regex = f'\.png$' - -#: W605:2:1 -regex = f''' -\.png$ -''' - -#: W605:2:6 -f( - f'\_' -) - -#: W605:4:6 -f""" -multi-line -literal -with \_ somewhere -in the middle -""" - -#: W605:1:38 -value = f'new line\nand invalid escape \_ here' - - -#: Okay -regex = fr'\.png$' -regex = f'\\.png$' -regex = fr''' -\.png$ -''' -regex = fr''' -\\.png$ -''' -s = f'\\' -regex = f'\w' # noqa -regex = f''' -\w -''' # noqa - -regex = f'\\\_' -value = f'\{{1}}' -value = f'\{1}' -value = f'{1:\}' -value = f"{f"\{1}"}" -value = rf"{f"\{1}"}" - -# Okay -value = rf'\{{1}}' -value = rf'\{1}' -value = rf'{1:\}' -value = f"{rf"\{1}"}" diff --git a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D.py b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D.py index 724490934ffaf..617231c5c81a9 100644 --- a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D.py +++ b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D.py @@ -713,5 +713,12 @@ def retain_extra_whitespace_not_overindented(): This is not overindented This is overindented, but since one line is not overindented this should not raise - And so is this, but it we should preserve the extra space on this line relative + And so is this, but it we should preserve the extra space on this line relative + """ + + +def inconsistent_indent_byte_size(): + """There's a non-breaking space (2-bytes) after 3 spaces (https://github.com/astral-sh/ruff/issues/9080). + +     Returns: """ diff --git a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D100.ipynb b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D100.ipynb new file mode 100644 index 0000000000000..b060eda1eac3b --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D100.ipynb @@ -0,0 +1,43 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "33faf7ad-a3fd-4ac4-a0c3-52e507ed49df", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello world!\n" + ] + } + ], + "source": [ + "print(\"Hello world!\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (ruff-playground)", + "language": "python", + "name": "ruff-playground" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D208.py b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D208.py new file mode 100644 index 0000000000000..4e99cf4b7fdf5 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D208.py @@ -0,0 +1,16 @@ +""" + Author +""" + + +class Platform: + """ Remove sampler + Args: +     Returns: + """ + + +def memory_test(): + """ +   参数含义:precision:精确到小数点后几位 + """ diff --git a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D400.py b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D400.py index 38547d4addd9a..3c6cc5bfce7b1 100644 --- a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D400.py +++ b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D400.py @@ -91,3 +91,12 @@ def f(rounds: list[int], number: int) -> bool: bool: was the round played? """ return number in rounds + + +def f(): + """ + My example + ========== + + My example explanation + """ diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_23.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_23.py new file mode 100644 index 0000000000000..456b9d1a7abd0 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_23.py @@ -0,0 +1,7 @@ +"""Test for type annotation parsing in `NamedTuple`.""" + +import typing + +User = typing.NamedTuple('User', **{'name': str, 'password': bytes}) +User = typing.NamedTuple('User', name=str, password=bytes) +User = typing.NamedTuple('User', [('name', str), ('password', bytes)]) diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py b/crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py index 760951260e24c..5032f42ff1d3a 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py @@ -50,7 +50,7 @@ def __doc__(self): return "Docstring" # Added in Python 3.12 - def __buffer__(self): + def __buffer__(self): return memoryview(b'') def __release_buffer__(self, buf): @@ -83,6 +83,10 @@ def _missing_(cls, value): def _(self): pass + # Allow custom dunder names (via setting). + def __special_custom_magic__(self): + pass + def __foo_bar__(): # this is not checked by the [bad-dunder-name] rule ... diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/no_method_decorator.py b/crates/ruff_linter/resources/test/fixtures/pylint/no_method_decorator.py new file mode 100644 index 0000000000000..e8351cb80ad61 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pylint/no_method_decorator.py @@ -0,0 +1,19 @@ +from random import choice + +class Fruit: + COLORS = [] + + def __init__(self, color): + self.color = color + + def pick_colors(cls, *args): # [no-classmethod-decorator] + """classmethod to pick fruit colors""" + cls.COLORS = args + + pick_colors = classmethod(pick_colors) + + def pick_one_color(): # [no-staticmethod-decorator] + """staticmethod to pick one fruit color""" + return choice(Fruit.COLORS) + + pick_one_color = staticmethod(pick_one_color) diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/self_assigning_variable.py b/crates/ruff_linter/resources/test/fixtures/pylint/self_assigning_variable.py index 288d6d6c6272e..05925a02f18a8 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/self_assigning_variable.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/self_assigning_variable.py @@ -23,6 +23,9 @@ (foo, (bar, baz)) = (foo, (bar, 1)) foo: int = foo bar: int = bar +foo = foo = bar +(foo, bar) = (foo, bar) = baz +(foo, bar) = baz = (foo, bar) = 1 # Non-errors. foo = bar diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/subprocess_run_without_check.py b/crates/ruff_linter/resources/test/fixtures/pylint/subprocess_run_without_check.py index b329ba45109ab..af5dbbc4d0feb 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/subprocess_run_without_check.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/subprocess_run_without_check.py @@ -3,6 +3,11 @@ # Errors. subprocess.run("ls") subprocess.run("ls", shell=True) +subprocess.run( + ["ls"], + shell=False, +) +subprocess.run(["ls"], **kwargs) # Non-errors. subprocess.run("ls", check=True) diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/too_many_arguments.py b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_arguments.py index 5271910cc53a4..43b2b178c04e0 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/too_many_arguments.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_arguments.py @@ -32,3 +32,16 @@ def f(x, y, z, *, u, v, w): # Too many arguments (6/5) def f(x, y, z, a, b, c, *, u, v, w): # Too many arguments (9/5) pass + + +from typing import override, overload + + +@override +def f(x, y, z, a, b, c, *, u, v, w): # OK + pass + + +@overload +def f(x, y, z, a, b, c, *, u, v, w): # OK + pass diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/too_many_positional.py b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_positional.py new file mode 100644 index 0000000000000..3c0fe2a2f5fb4 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_positional.py @@ -0,0 +1,30 @@ +def f(x, y, z, t, u, v, w, r): # Too many positional arguments (8/3) + pass + + +def f(x): # OK + pass + + +def f(x, y, z, _t, _u, _v, _w, r): # OK (underscore-prefixed names are ignored + pass + + +def f(x, y, z, *, u=1, v=1, r=1): # OK + pass + + +def f(x=1, y=1, z=1): # OK + pass + + +def f(x, y, z, /, u, v, w): # Too many positional arguments (6/3) + pass + + +def f(x, y, z, *, u, v, w): # OK + pass + + +def f(x, y, z, a, b, c, *, u, v, w): # Too many positional arguments (6/3) + pass diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/too_many_positional_params.py b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_positional_params.py new file mode 100644 index 0000000000000..dae87b5737a2c --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_positional_params.py @@ -0,0 +1,10 @@ +# Too many positional arguments (7/4) for max_positional=4 +# OK for dummy_variable_rgx ~ "skip_.*" +def f(w, x, y, z, skip_t, skip_u, skip_v): + pass + + +# Too many positional arguments (7/4) for max_args=4 +# Too many positional arguments (7/3) for dummy_variable_rgx ~ "skip_.*" +def f(w, x, y, z, t, u, v): + pass diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_dict_index_lookup.py b/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_dict_index_lookup.py new file mode 100644 index 0000000000000..d3daeb83c97b8 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_dict_index_lookup.py @@ -0,0 +1,40 @@ +FRUITS = {"apple": 1, "orange": 10, "berry": 22} + +def fix_these(): + [FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()] # PLR1733 + {FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 + {fruit_name: FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 + + for fruit_name, fruit_count in FRUITS.items(): + print(FRUITS[fruit_name]) # PLR1733 + blah = FRUITS[fruit_name] # PLR1733 + assert FRUITS[fruit_name] == "pear" # PLR1733 + + +def dont_fix_these(): + # once there is an assignment to the dict[index], we stop emitting diagnostics + for fruit_name, fruit_count in FRUITS.items(): + FRUITS[fruit_name] = 0 # OK + assert FRUITS[fruit_name] == 0 # OK + + # once there is an assignment to the key, we stop emitting diagnostics + for fruit_name, fruit_count in FRUITS.items(): + fruit_name = 0 # OK + assert FRUITS[fruit_name] == 0 # OK + + # once there is an assignment to the value, we stop emitting diagnostics + for fruit_name, fruit_count in FRUITS.items(): + if fruit_count < 5: + fruit_count = -fruit_count + assert FRUITS[fruit_name] == 0 # OK + + +def value_intentionally_unused(): + [FRUITS[fruit_name] for fruit_name, _ in FRUITS.items()] # OK + {FRUITS[fruit_name] for fruit_name, _ in FRUITS.items()} # OK + {fruit_name: FRUITS[fruit_name] for fruit_name, _ in FRUITS.items()} # OK + + for fruit_name, _ in FRUITS.items(): + print(FRUITS[fruit_name]) # OK + blah = FRUITS[fruit_name] # OK + assert FRUITS[fruit_name] == "pear" # OK diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_list_index_lookup.py b/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_list_index_lookup.py new file mode 100644 index 0000000000000..8911c8bd26c96 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_list_index_lookup.py @@ -0,0 +1,64 @@ +import builtins + +letters = ["a", "b", "c"] + + +def fix_these(): + [letters[index] for index, letter in enumerate(letters)] # PLR1736 + {letters[index] for index, letter in enumerate(letters)} # PLR1736 + {letter: letters[index] for index, letter in enumerate(letters)} # PLR1736 + + for index, letter in enumerate(letters): + print(letters[index]) # PLR1736 + blah = letters[index] # PLR1736 + assert letters[index] == "d" # PLR1736 + + for index, letter in builtins.enumerate(letters): + print(letters[index]) # PLR1736 + blah = letters[index] # PLR1736 + assert letters[index] == "d" # PLR1736 + + +def dont_fix_these(): + # once there is an assignment to the sequence[index], we stop emitting diagnostics + for index, letter in enumerate(letters): + letters[index] = "d" # OK + letters[index] += "e" # OK + assert letters[index] == "de" # OK + + # once there is an assignment to the index, we stop emitting diagnostics + for index, letter in enumerate(letters): + index += 1 # OK + print(letters[index]) # OK + + # once there is an assignment to the sequence, we stop emitting diagnostics + for index, letter in enumerate(letters): + letters = ["d", "e", "f"] # OK + print(letters[index]) # OK + + # once there is an assignment to the value, we stop emitting diagnostics + for index, letter in enumerate(letters): + letter = "d" + print(letters[index]) # OK + + # once there is an deletion from or of the sequence or index, we stop emitting diagnostics + for index, letter in enumerate(letters): + del letters[index] # OK + print(letters[index]) # OK + for index, letter in enumerate(letters): + del letters # OK + print(letters[index]) # OK + for index, letter in enumerate(letters): + del index # OK + print(letters[index]) # OK + + +def value_intentionally_unused(): + [letters[index] for index, _ in enumerate(letters)] # OK + {letters[index] for index, _ in enumerate(letters)} # OK + {index: letters[index] for index, _ in enumerate(letters)} # OK + + for index, _ in enumerate(letters): + print(letters[index]) # OK + blah = letters[index] # OK + letters[index] = "d" # OK diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/unspecified_encoding.py b/crates/ruff_linter/resources/test/fixtures/pylint/unspecified_encoding.py index 216fd83513a9c..01c12c9fc4c77 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/unspecified_encoding.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/unspecified_encoding.py @@ -42,3 +42,30 @@ def func(*args, **kwargs): tempfile.SpooledTemporaryFile(0, "w", -1, "utf-8") tempfile.SpooledTemporaryFile(0, "wb") tempfile.SpooledTemporaryFile(0, ) + +open("test.txt",) +open() +open( + "test.txt", # comment +) +open( + "test.txt", + # comment +) +open(("test.txt"),) +open( + ("test.txt"), # comment +) +open( + ("test.txt"), + # comment +) + +open((("test.txt")),) +open( + (("test.txt")), # comment +) +open( + (("test.txt")), + # comment +) diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP031_0.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP031_0.py index 9544e11c4c632..00fef079b6e30 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP031_0.py +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP031_0.py @@ -110,3 +110,10 @@ "%s" % ( x, # comment ) + + +path = "%s-%s-%s.pem" % ( + safe_domain_name(cn), # common name, which should be filename safe because it is IDNA-encoded, but in case of a malformed cert make sure it's ok to use as a filename + cert.not_valid_after.date().isoformat().replace("-", ""), # expiration date + hexlify(cert.fingerprint(hashes.SHA256())).decode("ascii")[0:8], # fingerprint prefix +) diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB152.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB152.py index 5e1bfbb16640d..e9339a86fcd3d 100644 --- a/crates/ruff_linter/resources/test/fixtures/refurb/FURB152.py +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB152.py @@ -5,3 +5,11 @@ C = 6.28 * r # FURB152 e = 2.71 # FURB152 + +r = 3.15 # OK + +r = 3.141 # FURB152 + +r = 3.1415 # FURB152 + +e = 2.7 # OK diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB163.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB163.py new file mode 100644 index 0000000000000..52b6619badb33 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB163.py @@ -0,0 +1,52 @@ +import math + +from math import e as special_e +from math import log as special_log + +# Errors. +math.log(1, 2) +math.log(1, 10) +math.log(1, math.e) +foo = ... +math.log(foo, 2) +math.log(foo, 10) +math.log(foo, math.e) +math.log(1, special_e) +special_log(1, 2) +special_log(1, 10) +special_log(1, math.e) +special_log(1, special_e) +math.log(1, 2.0) +math.log(1, 10.0) + +# Ok. +math.log2(1) +math.log10(1) +math.log(1) +math.log(1, 3) +math.log(1, math.pi) + +two = 2 +math.log(1, two) + +ten = 10 +math.log(1, ten) + +e = math.e +math.log(1, e) + +math.log2(1, 10) # math.log2 takes only one argument. +math.log10(1, 2) # math.log10 takes only one argument. + +math.log(1, base=2) # math.log does not accept keyword arguments. + +def log(*args): + print(f"Logging: {args}") + + +log(1, 2) +log(1, 10) +log(1, math.e) + +math.log(1, 2.0001) +math.log(1, 10.0001) diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB181.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB181.py new file mode 100644 index 0000000000000..559f67ee30442 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB181.py @@ -0,0 +1,57 @@ +import hashlib +from hashlib import ( + blake2b, + blake2s, + md5, + sha1, + sha3_224, + sha3_256, + sha3_384, + sha3_512, + sha224, +) +from hashlib import sha256 +from hashlib import sha256 as hash_algo +from hashlib import sha384, sha512, shake_128, shake_256 + +# these will match + +blake2b().digest().hex() +blake2s().digest().hex() +md5().digest().hex() +sha1().digest().hex() +sha224().digest().hex() +sha256().digest().hex() +sha384().digest().hex() +sha3_224().digest().hex() +sha3_256().digest().hex() +sha3_384().digest().hex() +sha3_512().digest().hex() +sha512().digest().hex() +shake_128().digest(10).hex() +shake_256().digest(10).hex() + +hashlib.sha256().digest().hex() + +sha256(b"text").digest().hex() + +hash_algo().digest().hex() + +# not yet supported +h = sha256() +h.digest().hex() + + +# these will not + +sha256().digest() +sha256().digest().hex("_") +sha256().digest().hex(bytes_per_sep=4) +sha256().hexdigest() + +class Hash: + def digest(self) -> bytes: + return b"" + + +Hash().digest().hex() diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF006.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF006.py index eedce2563153b..6c7792d5c4391 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF006.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF006.py @@ -63,11 +63,29 @@ def f(): tasks = [asyncio.create_task(task) for task in tasks] -# OK (false negative) +# Error def f(): task = asyncio.create_task(coordinator.ws_connect()) +# Error +def f(): + loop = asyncio.get_running_loop() + task: asyncio.Task = loop.create_task(coordinator.ws_connect()) + + +# OK (potential false negative) +def f(): + task = asyncio.create_task(coordinator.ws_connect()) + background_tasks.add(task) + + +# OK +async def f(): + task = asyncio.create_task(coordinator.ws_connect()) + await task + + # OK (potential false negative) def f(): do_nothing_with_the_task(asyncio.create_task(coordinator.ws_connect())) @@ -88,3 +106,19 @@ def f(): def f(): loop = asyncio.get_running_loop() loop.do_thing(coordinator.ws_connect()) + + +# OK +async def f(): + task = unused = asyncio.create_task(coordinator.ws_connect()) + await task + + +# OK (false negative) +async def f(): + task = unused = asyncio.create_task(coordinator.ws_connect()) + + +# OK +async def f(): + task[i] = asyncio.create_task(coordinator.ws_connect()) diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF012.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF012.py index ef58e45df1cb4..aa9d54d8b7bdd 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF012.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF012.py @@ -48,3 +48,14 @@ class E(Struct): without_annotation = [] class_variable: ClassVar[list[int]] = [] final_variable: Final[list[int]] = [] + + +from pydantic_settings import BaseSettings + + +class F(BaseSettings): + mutable_default: list[int] = [] + immutable_annotation: Sequence[int] = [] + without_annotation = [] + class_variable: ClassVar[list[int]] = [] + final_variable: Final[list[int]] = [] diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_3.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_3.py index 64f9cd12c49a4..17e6367ad0592 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_3.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_3.py @@ -23,3 +23,6 @@ print(a) # noqa: E501, F821 # comment print(a) # noqa: E501, F821 comment print(a) # noqa: E501, F821 comment + +print(a) # comment with unicode µ # noqa: E501 +print(a) # comment with unicode µ # noqa: E501, F821 diff --git a/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py b/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py index 987c321907880..e5b4757691364 100644 --- a/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py +++ b/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py @@ -109,3 +109,13 @@ def fine(): a = 1 except Exception: error("Context message here", exc_info=sys.exc_info()) + + +def nested(): + try: + a = 1 + except Exception: + try: + b = 2 + except Exception: + error("Context message here") diff --git a/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY401.py b/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY401.py index 0aa58677837fd..968e0f957b804 100644 --- a/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY401.py +++ b/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY401.py @@ -126,3 +126,25 @@ def main_function(): except Exception as ex: exception(f"Found an error: {er}") exception(f"Found an error: {ex.field}") + + +def nested(): + try: + process() + handle() + except Exception as ex: + try: + finish() + except Exception as ex: + logger.exception(f"Found an error: {ex}") # TRY401 + + +def nested(): + try: + process() + handle() + except Exception as ex: + try: + finish() + except Exception: + logger.exception(f"Found an error: {ex}") # TRY401 diff --git a/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs b/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs index 0fbc85f5552fa..e279dd5fbf7e9 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs @@ -3,11 +3,12 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::codes::Rule; -use crate::rules::{flake8_import_conventions, flake8_pyi, pyflakes, pylint}; +use crate::rules::{flake8_import_conventions, flake8_pyi, pyflakes, pylint, ruff}; /// Run lint rules over the [`Binding`]s. pub(crate) fn bindings(checker: &mut Checker) { if !checker.any_enabled(&[ + Rule::AsyncioDanglingTask, Rule::InvalidAllFormat, Rule::InvalidAllObject, Rule::NonAsciiName, @@ -71,5 +72,12 @@ pub(crate) fn bindings(checker: &mut Checker) { checker.diagnostics.push(diagnostic); } } + if checker.enabled(Rule::AsyncioDanglingTask) { + if let Some(diagnostic) = + ruff::rules::asyncio_dangling_binding(binding, &checker.semantic) + { + checker.diagnostics.push(diagnostic); + } + } } } diff --git a/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs b/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs index 27c9a6b7c79e2..66d0ad25273e9 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs @@ -59,6 +59,7 @@ pub(crate) fn deferred_scopes(checker: &mut Checker) { flake8_type_checking::helpers::is_valid_runtime_import( binding, &checker.semantic, + &checker.settings.flake8_type_checking, ) }) .collect() diff --git a/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs b/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs index f4c40279096b2..6cafa66f49e32 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs @@ -158,21 +158,23 @@ pub(crate) fn definitions(checker: &mut Checker) { } // Extract a `Docstring` from a `Definition`. - let Some(expr) = docstring else { + let Some(string_literal) = docstring else { pydocstyle::rules::not_missing(checker, definition, *visibility); continue; }; - let contents = checker.locator().slice(expr); + let contents = checker.locator().slice(string_literal); let indentation = checker.locator().slice(TextRange::new( - checker.locator.line_start(expr.start()), - expr.start(), + checker.locator.line_start(string_literal.start()), + string_literal.start(), )); - if expr.implicit_concatenated { + if string_literal.value.is_implicit_concatenated() { #[allow(deprecated)] - let location = checker.locator.compute_source_location(expr.start()); + let location = checker + .locator + .compute_source_location(string_literal.start()); warn_user!( "Docstring at {}:{}:{} contains implicit string concatenation; ignoring...", relativize_path(checker.path), @@ -186,7 +188,7 @@ pub(crate) fn definitions(checker: &mut Checker) { let body_range = raw_contents_range(contents).unwrap(); let docstring = Docstring { definition, - expr, + expr: string_literal, contents, body_range, indentation, diff --git a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs index 8ce687e0f6a73..257db41db5413 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs @@ -205,19 +205,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { ExprContext::Store => { if checker.enabled(Rule::NonLowercaseVariableInFunction) { if checker.semantic.current_scope().kind.is_function() { - // Ignore globals. - if !checker - .semantic - .current_scope() - .get(id) - .is_some_and(|binding_id| { - checker.semantic.binding(binding_id).is_global() - }) - { - pep8_naming::rules::non_lowercase_variable_in_function( - checker, expr, id, - ); - } + pep8_naming::rules::non_lowercase_variable_in_function( + checker, expr, id, + ); } } if checker.enabled(Rule::MixedCaseVariableInClassScope) { @@ -366,21 +356,29 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { Rule::FString, // flynt Rule::StaticJoinToFString, + // refurb + Rule::HashlibDigestHex, ]) { if let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() { let attr = attr.as_str(); - if let Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) = - value.as_ref() + if let Expr::StringLiteral(ast::ExprStringLiteral { + value: string_value, + .. + }) = value.as_ref() { if attr == "join" { // "...".join(...) call if checker.enabled(Rule::StaticJoinToFString) { - flynt::rules::static_join_to_fstring(checker, expr, string); + flynt::rules::static_join_to_fstring( + checker, + expr, + string_value.to_str(), + ); } } else if attr == "format" { // "...".format(...) call let location = expr.range(); - match pyflakes::format::FormatSummary::try_from(string.as_ref()) { + match pyflakes::format::FormatSummary::try_from(string_value.to_str()) { Err(e) => { if checker.enabled(Rule::StringDotFormatInvalidFormat) { checker.diagnostics.push(Diagnostic::new( @@ -425,7 +423,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { if checker.enabled(Rule::BadStringFormatCharacter) { pylint::rules::bad_string_format_character::call( - checker, string, location, + checker, + string_value.to_str(), + location, ); } } @@ -545,7 +545,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { flake8_bugbear::rules::no_explicit_stacklevel(checker, call); } if checker.enabled(Rule::UnnecessaryDictKwargs) { - flake8_pie::rules::unnecessary_dict_kwargs(checker, expr, keywords); + flake8_pie::rules::unnecessary_dict_kwargs(checker, call); } if checker.enabled(Rule::UnnecessaryRangeStart) { flake8_pie::rules::unnecessary_range_start(checker, call); @@ -583,6 +583,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { if checker.enabled(Rule::HashlibInsecureHashFunction) { flake8_bandit::rules::hashlib_insecure_hash_functions(checker, call); } + if checker.enabled(Rule::HashlibDigestHex) { + refurb::rules::hashlib_digest_hex(checker, call); + } if checker.enabled(Rule::RequestWithoutTimeout) { flake8_bandit::rules::request_without_timeout(checker, call); } @@ -612,6 +615,12 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { ]) { flake8_bandit::rules::shell_injection(checker, call); } + if checker.enabled(Rule::DjangoRawSql) { + flake8_bandit::rules::django_raw_sql(checker, call); + } + if checker.enabled(Rule::TarfileUnsafeMembers) { + flake8_bandit::rules::tarfile_unsafe_members(checker, call); + } if checker.enabled(Rule::UnnecessaryGeneratorList) { flake8_comprehensions::rules::unnecessary_generator_list( checker, expr, func, args, keywords, @@ -914,6 +923,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { if checker.enabled(Rule::PrintEmptyString) { refurb::rules::print_empty_string(checker, call); } + if checker.enabled(Rule::RedundantLogBase) { + refurb::rules::redundant_log_base(checker, call); + } if checker.enabled(Rule::QuadraticListSummation) { ruff::rules::quadratic_list_summation(checker, call); } @@ -982,15 +994,22 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { pylint::rules::await_outside_async(checker, expr); } } - Expr::FString(fstring @ ast::ExprFString { values, .. }) => { + Expr::FString(f_string_expr @ ast::ExprFString { value, .. }) => { if checker.enabled(Rule::FStringMissingPlaceholders) { - pyflakes::rules::f_string_missing_placeholders(fstring, checker); + pyflakes::rules::f_string_missing_placeholders(checker, f_string_expr); + } + if checker.enabled(Rule::ExplicitFStringTypeConversion) { + for f_string in value.f_strings() { + ruff::rules::explicit_f_string_type_conversion(checker, f_string); + } } if checker.enabled(Rule::HardcodedSQLExpression) { flake8_bandit::rules::hardcoded_sql_expression(checker, expr); } - if checker.enabled(Rule::ExplicitFStringTypeConversion) { - ruff::rules::explicit_f_string_type_conversion(checker, expr, values); + if checker.enabled(Rule::UnicodeKindPrefix) { + for string_literal in value.literals() { + pyupgrade::rules::unicode_kind_prefix(checker, string_literal); + } } } Expr::BinOp(ast::ExprBinOp { @@ -1021,7 +1040,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { Rule::PercentFormatUnsupportedFormatCharacter, ]) { let location = expr.range(); - match pyflakes::cformat::CFormatSummary::try_from(value.as_str()) { + match pyflakes::cformat::CFormatSummary::try_from(value.to_str()) { Err(CFormatError { typ: CFormatErrorType::UnsupportedFormatChar(c), .. @@ -1256,25 +1275,10 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { refurb::rules::math_constant(checker, number_literal); } } - Expr::BytesLiteral(_) => { - if checker.source_type.is_stub() && checker.enabled(Rule::StringOrBytesTooLong) { - flake8_pyi::rules::string_or_bytes_too_long(checker, expr); - } - } - Expr::StringLiteral(string) => { - if checker.enabled(Rule::HardcodedBindAllInterfaces) { - if let Some(diagnostic) = - flake8_bandit::rules::hardcoded_bind_all_interfaces(string) - { - checker.diagnostics.push(diagnostic); - } - } - if checker.enabled(Rule::HardcodedTempFile) { - flake8_bandit::rules::hardcoded_tmp_directory(checker, string); - } - if checker.source_type.is_stub() { - if checker.enabled(Rule::StringOrBytesTooLong) { - flake8_pyi::rules::string_or_bytes_too_long(checker, expr); + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { + if checker.enabled(Rule::UnicodeKindPrefix) { + for string_part in value { + pyupgrade::rules::unicode_kind_prefix(checker, string_part); } } } @@ -1311,6 +1315,12 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { range: _, }, ) => { + if checker.enabled(Rule::UnnecessaryListIndexLookup) { + pylint::rules::unnecessary_list_index_lookup_comprehension(checker, expr); + } + if checker.enabled(Rule::UnnecessaryDictIndexLookup) { + pylint::rules::unnecessary_dict_index_lookup_comprehension(checker, expr); + } if checker.enabled(Rule::UnnecessaryComprehension) { flake8_comprehensions::rules::unnecessary_list_set_comprehension( checker, expr, elt, generators, @@ -1335,6 +1345,12 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { range: _, }, ) => { + if checker.enabled(Rule::UnnecessaryListIndexLookup) { + pylint::rules::unnecessary_list_index_lookup_comprehension(checker, expr); + } + if checker.enabled(Rule::UnnecessaryDictIndexLookup) { + pylint::rules::unnecessary_dict_index_lookup_comprehension(checker, expr); + } if checker.enabled(Rule::UnnecessaryComprehension) { flake8_comprehensions::rules::unnecessary_list_set_comprehension( checker, expr, elt, generators, @@ -1358,6 +1374,12 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { generators, range: _, }) => { + if checker.enabled(Rule::UnnecessaryListIndexLookup) { + pylint::rules::unnecessary_list_index_lookup_comprehension(checker, expr); + } + if checker.enabled(Rule::UnnecessaryDictIndexLookup) { + pylint::rules::unnecessary_dict_index_lookup_comprehension(checker, expr); + } if checker.enabled(Rule::UnnecessaryComprehension) { flake8_comprehensions::rules::unnecessary_dict_comprehension( checker, expr, key, value, generators, @@ -1382,6 +1404,12 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { range: _, }, ) => { + if checker.enabled(Rule::UnnecessaryListIndexLookup) { + pylint::rules::unnecessary_list_index_lookup_comprehension(checker, expr); + } + if checker.enabled(Rule::UnnecessaryDictIndexLookup) { + pylint::rules::unnecessary_dict_index_lookup_comprehension(checker, expr); + } if checker.enabled(Rule::FunctionUsesLoopVariable) { flake8_bugbear::rules::function_uses_loop_variable(checker, &Node::Expr(expr)); } diff --git a/crates/ruff_linter/src/checkers/ast/analyze/mod.rs b/crates/ruff_linter/src/checkers/ast/analyze/mod.rs index dd9ec2fbfd2ce..deeb55864b569 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/mod.rs @@ -10,6 +10,7 @@ pub(super) use module::module; pub(super) use parameter::parameter; pub(super) use parameters::parameters; pub(super) use statement::statement; +pub(super) use string_like::string_like; pub(super) use suite::suite; pub(super) use unresolved_references::unresolved_references; @@ -25,5 +26,6 @@ mod module; mod parameter; mod parameters; mod statement; +mod string_like; mod suite; mod unresolved_references; diff --git a/crates/ruff_linter/src/checkers/ast/analyze/statement.rs b/crates/ruff_linter/src/checkers/ast/analyze/statement.rs index 0ad8dc16e5777..714ae3e4e3943 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/statement.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/statement.rs @@ -248,7 +248,10 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { pylint::rules::property_with_parameters(checker, stmt, decorator_list, parameters); } if checker.enabled(Rule::TooManyArguments) { - pylint::rules::too_many_arguments(checker, parameters, stmt); + pylint::rules::too_many_arguments(checker, function_def); + } + if checker.enabled(Rule::TooManyPositional) { + pylint::rules::too_many_positional(checker, function_def); } if checker.enabled(Rule::TooManyReturnStatements) { if let Some(diagnostic) = pylint::rules::too_many_return_statements( @@ -384,31 +387,23 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { range: _, }, ) => { + if checker.enabled(Rule::NoClassmethodDecorator) { + pylint::rules::no_classmethod_decorator(checker, class_def); + } + if checker.enabled(Rule::NoStaticmethodDecorator) { + pylint::rules::no_staticmethod_decorator(checker, class_def); + } if checker.enabled(Rule::DjangoNullableModelStringField) { flake8_django::rules::nullable_model_string_field(checker, body); } if checker.enabled(Rule::DjangoExcludeWithModelForm) { - if let Some(diagnostic) = flake8_django::rules::exclude_with_model_form( - checker, - arguments.as_deref(), - body, - ) { - checker.diagnostics.push(diagnostic); - } + flake8_django::rules::exclude_with_model_form(checker, class_def); } if checker.enabled(Rule::DjangoAllWithModelForm) { - if let Some(diagnostic) = - flake8_django::rules::all_with_model_form(checker, arguments.as_deref(), body) - { - checker.diagnostics.push(diagnostic); - } + flake8_django::rules::all_with_model_form(checker, class_def); } if checker.enabled(Rule::DjangoUnorderedBodyContentInModel) { - flake8_django::rules::unordered_body_content_in_model( - checker, - arguments.as_deref(), - body, - ); + flake8_django::rules::unordered_body_content_in_model(checker, class_def); } if !checker.source_type.is_stub() { if checker.enabled(Rule::DjangoModelWithoutDunderStr) { @@ -1269,7 +1264,13 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { perflint::rules::manual_dict_comprehension(checker, target, body); } if checker.enabled(Rule::UnnecessaryListCast) { - perflint::rules::unnecessary_list_cast(checker, iter); + perflint::rules::unnecessary_list_cast(checker, iter, body); + } + if checker.enabled(Rule::UnnecessaryListIndexLookup) { + pylint::rules::unnecessary_list_index_lookup(checker, for_stmt); + } + if checker.enabled(Rule::UnnecessaryDictIndexLookup) { + pylint::rules::unnecessary_dict_index_lookup(checker, for_stmt); } if !is_async { if checker.enabled(Rule::ReimplementedBuiltin) { @@ -1355,7 +1356,6 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { } } Stmt::Assign(assign @ ast::StmtAssign { targets, value, .. }) => { - checker.enabled(Rule::NonAsciiName); if checker.enabled(Rule::LambdaAssignment) { if let [target] = &targets[..] { pycodestyle::rules::lambda_assignment(checker, target, value, None, stmt); @@ -1407,9 +1407,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { } } if checker.settings.rules.enabled(Rule::SelfAssigningVariable) { - if let [target] = targets.as_slice() { - pylint::rules::self_assigning_variable(checker, target, value); - } + pylint::rules::self_assignment(checker, assign); } if checker.settings.rules.enabled(Rule::TypeParamNameMismatch) { pylint::rules::type_param_name_mismatch(checker, value, targets); @@ -1479,9 +1477,9 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { stmt, ); } - if checker.enabled(Rule::SelfAssigningVariable) { - pylint::rules::self_assigning_variable(checker, target, value); - } + } + if checker.enabled(Rule::SelfAssigningVariable) { + pylint::rules::self_annotated_assignment(checker, assign_stmt); } if checker.enabled(Rule::UnintentionalTypeAnnotation) { flake8_bugbear::rules::unintentional_type_annotation( @@ -1525,6 +1523,14 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { } } } + Stmt::TypeAlias(ast::StmtTypeAlias { name, .. }) => { + if checker.enabled(Rule::SnakeCaseTypeAlias) { + flake8_pyi::rules::snake_case_type_alias(checker, name); + } + if checker.enabled(Rule::TSuffixedTypeAlias) { + flake8_pyi::rules::t_suffixed_type_alias(checker, name); + } + } Stmt::Delete(delete @ ast::StmtDelete { targets, range: _ }) => { if checker.enabled(Rule::GlobalStatement) { for target in targets { @@ -1551,7 +1557,11 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { pylint::rules::named_expr_without_context(checker, value); } if checker.enabled(Rule::AsyncioDanglingTask) { - ruff::rules::asyncio_dangling_task(checker, value); + if let Some(diagnostic) = + ruff::rules::asyncio_dangling_task(value, checker.semantic()) + { + checker.diagnostics.push(diagnostic); + } } if checker.enabled(Rule::RepeatedAppend) { refurb::rules::repeated_append(checker, stmt); diff --git a/crates/ruff_linter/src/checkers/ast/analyze/string_like.rs b/crates/ruff_linter/src/checkers/ast/analyze/string_like.rs new file mode 100644 index 0000000000000..c3c8fb3367eec --- /dev/null +++ b/crates/ruff_linter/src/checkers/ast/analyze/string_like.rs @@ -0,0 +1,20 @@ +use ruff_python_ast::StringLike; + +use crate::checkers::ast::Checker; +use crate::codes::Rule; +use crate::rules::{flake8_bandit, flake8_pyi}; + +/// Run lint rules over a [`StringLike`] syntax nodes. +pub(crate) fn string_like(string_like: StringLike, checker: &mut Checker) { + if checker.enabled(Rule::HardcodedBindAllInterfaces) { + flake8_bandit::rules::hardcoded_bind_all_interfaces(checker, string_like); + } + if checker.enabled(Rule::HardcodedTempFile) { + flake8_bandit::rules::hardcoded_tmp_directory(checker, string_like); + } + if checker.source_type.is_stub() { + if checker.enabled(Rule::StringOrBytesTooLong) { + flake8_pyi::rules::string_or_bytes_too_long(checker, string_like); + } + } +} diff --git a/crates/ruff_linter/src/checkers/ast/annotation.rs b/crates/ruff_linter/src/checkers/ast/annotation.rs new file mode 100644 index 0000000000000..aca5fc6c629ff --- /dev/null +++ b/crates/ruff_linter/src/checkers/ast/annotation.rs @@ -0,0 +1,66 @@ +use ruff_python_semantic::{ScopeKind, SemanticModel}; + +use crate::rules::flake8_type_checking; +use crate::settings::LinterSettings; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(super) enum AnnotationContext { + /// Python will evaluate the annotation at runtime, but it's not _required_ and, as such, could + /// be quoted to convert it into a typing-only annotation. + /// + /// For example: + /// ```python + /// from pandas import DataFrame + /// + /// def foo() -> DataFrame: + /// ... + /// ``` + /// + /// Above, Python will evaluate `DataFrame` at runtime in order to add it to `__annotations__`. + RuntimeEvaluated, + /// Python will evaluate the annotation at runtime, and it's required to be available at + /// runtime, as a library (like Pydantic) needs access to it. + RuntimeRequired, + /// The annotation is only evaluated at type-checking time. + TypingOnly, +} + +impl AnnotationContext { + pub(super) fn from_model(semantic: &SemanticModel, settings: &LinterSettings) -> Self { + // If the annotation is in a class scope (e.g., an annotated assignment for a + // class field), and that class is marked as annotation as runtime-required. + if semantic + .current_scope() + .kind + .as_class() + .is_some_and(|class_def| { + flake8_type_checking::helpers::runtime_required_class( + class_def, + &settings.flake8_type_checking.runtime_required_base_classes, + &settings.flake8_type_checking.runtime_required_decorators, + semantic, + ) + }) + { + return Self::RuntimeRequired; + } + + // If `__future__` annotations are enabled, then annotations are never evaluated + // at runtime, so we can treat them as typing-only. + if semantic.future_annotations() { + return Self::TypingOnly; + } + + // Otherwise, if we're in a class or module scope, then the annotation needs to + // be available at runtime. + // See: https://docs.python.org/3/reference/simple_stmts.html#annotated-assignment-statements + if matches!( + semantic.current_scope().kind, + ScopeKind::Class(_) | ScopeKind::Module + ) { + return Self::RuntimeEvaluated; + } + + Self::TypingOnly + } +} diff --git a/crates/ruff_linter/src/checkers/ast/mod.rs b/crates/ruff_linter/src/checkers/ast/mod.rs index 20b9ea2756b43..1c510f1cbb8d9 100644 --- a/crates/ruff_linter/src/checkers/ast/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/mod.rs @@ -37,18 +37,19 @@ use ruff_python_ast::{ use ruff_text_size::{Ranged, TextRange, TextSize}; use ruff_diagnostics::{Diagnostic, IsolationLevel}; +use ruff_notebook::CellOffsets; use ruff_python_ast::all::{extract_all_names, DunderAllFlags}; use ruff_python_ast::helpers::{ collect_import_from_member, extract_handled_exceptions, to_module_path, }; use ruff_python_ast::identifier::Identifier; use ruff_python_ast::str::trailing_quote; -use ruff_python_ast::visitor::{walk_except_handler, walk_pattern, Visitor}; +use ruff_python_ast::visitor::{walk_except_handler, walk_f_string_element, walk_pattern, Visitor}; use ruff_python_ast::{helpers, str, visitor, PySourceType}; use ruff_python_codegen::{Generator, Quote, Stylist}; use ruff_python_index::Indexer; use ruff_python_parser::typing::{parse_type_annotation, AnnotationKind}; -use ruff_python_semantic::analyze::{typing, visibility}; +use ruff_python_semantic::analyze::{imports, typing, visibility}; use ruff_python_semantic::{ BindingFlags, BindingId, BindingKind, Exceptions, Export, FromImport, Globals, Import, Module, ModuleKind, NodeId, ScopeId, ScopeKind, SemanticModel, SemanticModelFlags, Snapshot, @@ -57,6 +58,7 @@ use ruff_python_semantic::{ use ruff_python_stdlib::builtins::{IPYTHON_BUILTINS, MAGIC_GLOBALS, PYTHON_BUILTINS}; use ruff_source_file::Locator; +use crate::checkers::ast::annotation::AnnotationContext; use crate::checkers::ast::deferred::Deferred; use crate::docstrings::extraction::ExtractionTarget; use crate::importer::Importer; @@ -67,6 +69,7 @@ use crate::settings::{flags, LinterSettings}; use crate::{docstrings, noqa}; mod analyze; +mod annotation; mod deferred; pub(crate) struct Checker<'a> { @@ -78,6 +81,8 @@ pub(crate) struct Checker<'a> { module_path: Option<&'a [String]>, /// The [`PySourceType`] of the current file. pub(crate) source_type: PySourceType, + /// The [`CellOffsets`] for the current file, if it's a Jupyter notebook. + cell_offsets: Option<&'a CellOffsets>, /// The [`flags::Noqa`] for the current analysis (i.e., whether to respect suppression /// comments). noqa: flags::Noqa, @@ -104,6 +109,8 @@ pub(crate) struct Checker<'a> { pub(crate) diagnostics: Vec, /// The list of names already seen by flake8-bugbear diagnostics, to avoid duplicate violations.. pub(crate) flake8_bugbear_seen: Vec, + /// The end offset of the last visited statement. + last_stmt_end: TextSize, } impl<'a> Checker<'a> { @@ -120,6 +127,7 @@ impl<'a> Checker<'a> { indexer: &'a Indexer, importer: Importer<'a>, source_type: PySourceType, + cell_offsets: Option<&'a CellOffsets>, ) -> Checker<'a> { Checker { settings, @@ -137,6 +145,8 @@ impl<'a> Checker<'a> { deferred: Deferred::default(), diagnostics: Vec::default(), flake8_bugbear_seen: Vec::default(), + cell_offsets, + last_stmt_end: TextSize::default(), } } } @@ -225,6 +235,11 @@ impl<'a> Checker<'a> { self.package } + /// The [`CellOffsets`] for the current file, if it's a Jupyter notebook. + pub(crate) const fn cell_offsets(&self) -> Option<&'a CellOffsets> { + self.cell_offsets + } + /// Returns whether the given rule should be checked. #[inline] pub(crate) const fn enabled(&self, rule: Rule) -> bool { @@ -258,6 +273,18 @@ where // Step 0: Pre-processing self.semantic.push_node(stmt); + // For Jupyter Notebooks, we'll reset the `IMPORT_BOUNDARY` flag when + // we encounter a cell boundary. + if self.source_type.is_ipynb() + && self.semantic.at_top_level() + && self.semantic.seen_import_boundary() + && self.cell_offsets.is_some_and(|cell_offsets| { + cell_offsets.has_cell_boundary(TextRange::new(self.last_stmt_end, stmt.start())) + }) + { + self.semantic.flags -= SemanticModelFlags::IMPORT_BOUNDARY; + } + // Track whether we've seen docstrings, non-imports, etc. match stmt { Stmt::ImportFrom(ast::StmtImportFrom { module, names, .. }) => { @@ -278,9 +305,12 @@ where } _ => { self.semantic.flags |= SemanticModelFlags::FUTURES_BOUNDARY; - if !self.semantic.seen_import_boundary() - && !helpers::is_assignment_to_a_dunder(stmt) - && !helpers::in_nested_block(self.semantic.current_statements()) + if !(self.semantic.seen_import_boundary() + || helpers::is_assignment_to_a_dunder(stmt) + || helpers::in_nested_block(self.semantic.current_statements()) + || imports::is_matplotlib_activation(stmt, self.semantic()) + || self.settings.preview.is_enabled() + && imports::is_sys_path_modification(stmt, self.semantic())) { self.semantic.flags |= SemanticModelFlags::IMPORT_BOUNDARY; } @@ -467,6 +497,13 @@ where // are enabled. let runtime_annotation = !self.semantic.future_annotations(); + // The first parameter may be a single dispatch. + let mut singledispatch = + flake8_type_checking::helpers::is_singledispatch_implementation( + function_def, + self.semantic(), + ); + self.semantic.push_scope(ScopeKind::Type); if let Some(type_params) = type_params { @@ -480,8 +517,10 @@ where .chain(¶meters.kwonlyargs) { if let Some(expr) = ¶meter_with_default.parameter.annotation { - if runtime_annotation { - self.visit_runtime_annotation(expr); + if singledispatch { + self.visit_runtime_required_annotation(expr); + } else if runtime_annotation { + self.visit_runtime_evaluated_annotation(expr); } else { self.visit_annotation(expr); }; @@ -489,11 +528,12 @@ where if let Some(expr) = ¶meter_with_default.default { self.visit_expr(expr); } + singledispatch = false; } if let Some(arg) = ¶meters.vararg { if let Some(expr) = &arg.annotation { if runtime_annotation { - self.visit_runtime_annotation(expr); + self.visit_runtime_evaluated_annotation(expr); } else { self.visit_annotation(expr); }; @@ -502,7 +542,7 @@ where if let Some(arg) = ¶meters.kwarg { if let Some(expr) = &arg.annotation { if runtime_annotation { - self.visit_runtime_annotation(expr); + self.visit_runtime_evaluated_annotation(expr); } else { self.visit_annotation(expr); }; @@ -510,7 +550,7 @@ where } for expr in returns { if runtime_annotation { - self.visit_runtime_annotation(expr); + self.visit_runtime_evaluated_annotation(expr); } else { self.visit_annotation(expr); }; @@ -641,39 +681,16 @@ where value, .. }) => { - // If we're in a class or module scope, then the annotation needs to be - // available at runtime. - // See: https://docs.python.org/3/reference/simple_stmts.html#annotated-assignment-statements - let runtime_annotation = if self.semantic.future_annotations() { - if self.semantic.current_scope().kind.is_class() { - let baseclasses = &self - .settings - .flake8_type_checking - .runtime_evaluated_base_classes; - let decorators = &self - .settings - .flake8_type_checking - .runtime_evaluated_decorators; - flake8_type_checking::helpers::runtime_evaluated( - baseclasses, - decorators, - &self.semantic, - ) - } else { - false + match AnnotationContext::from_model(&self.semantic, self.settings) { + AnnotationContext::RuntimeRequired => { + self.visit_runtime_required_annotation(annotation); } - } else { - matches!( - self.semantic.current_scope().kind, - ScopeKind::Class(_) | ScopeKind::Module - ) - }; - - if runtime_annotation { - self.visit_runtime_annotation(annotation); - } else { - self.visit_annotation(annotation); + AnnotationContext::RuntimeEvaluated => { + self.visit_runtime_evaluated_annotation(annotation); + } + AnnotationContext::TypingOnly => self.visit_annotation(annotation), } + if let Some(expr) = value { if self.semantic.match_typing_expr(annotation, "TypeAlias") { self.visit_type_definition(expr); @@ -769,6 +786,7 @@ where self.semantic.flags = flags_snapshot; self.semantic.pop_node(); + self.last_stmt_end = stmt.end(); } fn visit_annotation(&mut self, expr: &'b Expr) { @@ -780,8 +798,7 @@ where fn visit_expr(&mut self, expr: &'b Expr) { // Step 0: Pre-processing - if !self.semantic.in_f_string() - && !self.semantic.in_literal() + if !self.semantic.in_typing_literal() && !self.semantic.in_deferred_type_definition() && self.semantic.in_type_definition() && self.semantic.future_annotations() @@ -789,7 +806,7 @@ where if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = expr { self.deferred.string_type_definitions.push(( expr.range(), - value, + value.to_str(), self.semantic.snapshot(), )); } else { @@ -1014,33 +1031,54 @@ where if let Some(arg) = args.next() { self.visit_non_type_definition(arg); } + for arg in args { - if let Expr::List(ast::ExprList { elts, .. }) - | Expr::Tuple(ast::ExprTuple { elts, .. }) = arg - { - for elt in elts { - match elt { - Expr::List(ast::ExprList { elts, .. }) - | Expr::Tuple(ast::ExprTuple { elts, .. }) - if elts.len() == 2 => - { - self.visit_non_type_definition(&elts[0]); - self.visit_type_definition(&elts[1]); - } - _ => { - self.visit_non_type_definition(elt); + match arg { + // Ex) NamedTuple("a", [("a", int)]) + Expr::List(ast::ExprList { elts, .. }) + | Expr::Tuple(ast::ExprTuple { elts, .. }) => { + for elt in elts { + match elt { + Expr::List(ast::ExprList { elts, .. }) + | Expr::Tuple(ast::ExprTuple { elts, .. }) + if elts.len() == 2 => + { + self.visit_non_type_definition(&elts[0]); + self.visit_type_definition(&elts[1]); + } + _ => { + self.visit_non_type_definition(elt); + } } } } - } else { - self.visit_non_type_definition(arg); + _ => self.visit_non_type_definition(arg), } } - // Ex) NamedTuple("a", a=int) for keyword in keywords { - let Keyword { value, .. } = keyword; - self.visit_type_definition(value); + let Keyword { arg, value, .. } = keyword; + match (arg.as_ref(), value) { + // Ex) NamedTuple("a", **{"a": int}) + (None, Expr::Dict(ast::ExprDict { keys, values, .. })) => { + for (key, value) in keys.iter().zip(values) { + if let Some(key) = key.as_ref() { + self.visit_non_type_definition(key); + self.visit_type_definition(value); + } else { + self.visit_non_type_definition(value); + } + } + } + // Ex) NamedTuple("a", **obj) + (None, _) => { + self.visit_non_type_definition(value); + } + // Ex) NamedTuple("a", a=int) + _ => { + self.visit_type_definition(value); + } + } } } Some(typing::Callable::TypedDict) => { @@ -1142,7 +1180,7 @@ where ) { // Ex) Literal["Class"] Some(typing::SubscriptKind::Literal) => { - self.semantic.flags |= SemanticModelFlags::LITERAL; + self.semantic.flags |= SemanticModelFlags::TYPING_LITERAL; self.visit_expr(slice); self.visit_expr_context(ctx); @@ -1182,13 +1220,10 @@ where } } Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { - if self.semantic.in_type_definition() - && !self.semantic.in_literal() - && !self.semantic.in_f_string() - { + if self.semantic.in_type_definition() && !self.semantic.in_typing_literal() { self.deferred.string_type_definitions.push(( expr.range(), - value, + value.to_str(), self.semantic.snapshot(), )); } @@ -1215,6 +1250,13 @@ where // Step 4: Analysis analyze::expression(expr, self); + match expr { + Expr::StringLiteral(string_literal) => { + analyze::string_like(string_literal.into(), self); + } + Expr::BytesLiteral(bytes_literal) => analyze::string_like(bytes_literal.into(), self), + _ => {} + } self.semantic.flags = flags_snapshot; self.semantic.pop_node(); @@ -1270,17 +1312,6 @@ where self.semantic.flags = flags_snapshot; } - fn visit_format_spec(&mut self, format_spec: &'b Expr) { - match format_spec { - Expr::FString(ast::ExprFString { values, .. }) => { - for value in values { - self.visit_expr(value); - } - } - _ => unreachable!("Unexpected expression for format_spec"), - } - } - fn visit_parameters(&mut self, parameters: &'b Parameters) { // Step 1: Binding. // Bind, but intentionally avoid walking default expressions, as we handle them @@ -1390,6 +1421,16 @@ where .push((bound, self.semantic.snapshot())); } } + + fn visit_f_string_element(&mut self, f_string_element: &'b ast::FStringElement) { + // Step 2: Traversal + walk_f_string_element(self, f_string_element); + + // Step 4: Analysis + if let Some(literal) = f_string_element.as_literal() { + analyze::string_like(literal.into(), self); + } + } } impl<'a> Checker<'a> { @@ -1466,10 +1507,18 @@ impl<'a> Checker<'a> { self.semantic.flags = snapshot; } + /// Visit an [`Expr`], and treat it as a runtime-evaluated type annotation. + fn visit_runtime_evaluated_annotation(&mut self, expr: &'a Expr) { + let snapshot = self.semantic.flags; + self.semantic.flags |= SemanticModelFlags::RUNTIME_EVALUATED_ANNOTATION; + self.visit_type_definition(expr); + self.semantic.flags = snapshot; + } + /// Visit an [`Expr`], and treat it as a runtime-required type annotation. - fn visit_runtime_annotation(&mut self, expr: &'a Expr) { + fn visit_runtime_required_annotation(&mut self, expr: &'a Expr) { let snapshot = self.semantic.flags; - self.semantic.flags |= SemanticModelFlags::RUNTIME_ANNOTATION; + self.semantic.flags |= SemanticModelFlags::RUNTIME_REQUIRED_ANNOTATION; self.visit_type_definition(expr); self.semantic.flags = snapshot; } @@ -1921,6 +1970,7 @@ pub(crate) fn check_ast( path: &Path, package: Option<&Path>, source_type: PySourceType, + cell_offsets: Option<&CellOffsets>, ) -> Vec { let module_path = package.and_then(|package| to_module_path(package, path)); let module = Module { @@ -1949,6 +1999,7 @@ pub(crate) fn check_ast( indexer, Importer::new(python_ast, locator, stylist), source_type, + cell_offsets, ); checker.bind_builtins(); diff --git a/crates/ruff_linter/src/checkers/imports.rs b/crates/ruff_linter/src/checkers/imports.rs index 22cbe662f5c8b..5ecb477d85e29 100644 --- a/crates/ruff_linter/src/checkers/imports.rs +++ b/crates/ruff_linter/src/checkers/imports.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; use std::path::Path; use ruff_diagnostics::Diagnostic; +use ruff_notebook::CellOffsets; use ruff_python_ast::helpers::to_module_path; use ruff_python_ast::imports::{ImportMap, ModuleImport}; use ruff_python_ast::statement_visitor::StatementVisitor; @@ -17,7 +18,6 @@ use crate::registry::Rule; use crate::rules::isort; use crate::rules::isort::block::{Block, BlockBuilder}; use crate::settings::LinterSettings; -use crate::source_kind::SourceKind; fn extract_import_map(path: &Path, package: Option<&Path>, blocks: &[&Block]) -> Option { let Some(package) = package else { @@ -85,13 +85,13 @@ pub(crate) fn check_imports( stylist: &Stylist, path: &Path, package: Option<&Path>, - source_kind: &SourceKind, source_type: PySourceType, + cell_offsets: Option<&CellOffsets>, ) -> (Vec, Option) { // Extract all import blocks from the AST. let tracker = { let mut tracker = - BlockBuilder::new(locator, directives, source_type.is_stub(), source_kind); + BlockBuilder::new(locator, directives, source_type.is_stub(), cell_offsets); tracker.visit_body(python_ast); tracker }; diff --git a/crates/ruff_linter/src/checkers/noqa.rs b/crates/ruff_linter/src/checkers/noqa.rs index 7b4224c4e1e99..055f802ccc7c8 100644 --- a/crates/ruff_linter/src/checkers/noqa.rs +++ b/crates/ruff_linter/src/checkers/noqa.rs @@ -3,10 +3,10 @@ use std::path::Path; use itertools::Itertools; -use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; +use ruff_text_size::{Ranged, TextLen, TextRange}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; -use ruff_python_trivia::CommentRanges; +use ruff_python_trivia::{CommentRanges, PythonWhitespace}; use ruff_source_file::Locator; use crate::noqa; @@ -200,17 +200,11 @@ fn delete_noqa(range: TextRange, locator: &Locator) -> Edit { // Compute the leading space. let prefix = locator.slice(TextRange::new(line_range.start(), range.start())); - let leading_space = prefix - .rfind(|c: char| !c.is_whitespace()) - .map_or(prefix.len(), |i| prefix.len() - i - 1); - let leading_space_len = TextSize::try_from(leading_space).unwrap(); + let leading_space_len = prefix.text_len() - prefix.trim_whitespace_end().text_len(); // Compute the trailing space. let suffix = locator.slice(TextRange::new(range.end(), line_range.end())); - let trailing_space = suffix - .find(|c: char| !c.is_whitespace()) - .map_or(suffix.len(), |i| i); - let trailing_space_len = TextSize::try_from(trailing_space).unwrap(); + let trailing_space_len = suffix.text_len() - suffix.trim_whitespace_start().text_len(); // Ex) `# noqa` if line_range diff --git a/crates/ruff_linter/src/checkers/tokens.rs b/crates/ruff_linter/src/checkers/tokens.rs index b0f563c23b91f..ae7643d92f7e1 100644 --- a/crates/ruff_linter/src/checkers/tokens.rs +++ b/crates/ruff_linter/src/checkers/tokens.rs @@ -2,6 +2,8 @@ use std::path::Path; +use ruff_notebook::CellOffsets; +use ruff_python_ast::PySourceType; use ruff_python_parser::lexer::LexResult; use ruff_python_parser::Tok; @@ -25,7 +27,8 @@ pub(crate) fn check_tokens( locator: &Locator, indexer: &Indexer, settings: &LinterSettings, - is_stub: bool, + source_type: PySourceType, + cell_offsets: Option<&CellOffsets>, ) -> Vec { let mut diagnostics: Vec = vec![]; @@ -91,10 +94,6 @@ pub(crate) fn check_tokens( pycodestyle::rules::tab_indentation(&mut diagnostics, tokens, locator, indexer); } - if settings.rules.enabled(Rule::UnicodeKindPrefix) { - pyupgrade::rules::unicode_kind_prefix(&mut diagnostics, tokens); - } - if settings.rules.any_enabled(&[ Rule::InvalidCharacterBackspace, Rule::InvalidCharacterSub, @@ -112,7 +111,14 @@ pub(crate) fn check_tokens( Rule::MultipleStatementsOnOneLineSemicolon, Rule::UselessSemicolon, ]) { - pycodestyle::rules::compound_statements(&mut diagnostics, tokens, locator, indexer); + pycodestyle::rules::compound_statements( + &mut diagnostics, + tokens, + locator, + indexer, + source_type, + cell_offsets, + ); } if settings.rules.enabled(Rule::AvoidableEscapedQuote) && settings.flake8_quotes.avoid_escape { @@ -156,7 +162,7 @@ pub(crate) fn check_tokens( pyupgrade::rules::extraneous_parentheses(&mut diagnostics, tokens, locator); } - if is_stub && settings.rules.enabled(Rule::TypeCommentInStub) { + if source_type.is_stub() && settings.rules.enabled(Rule::TypeCommentInStub) { flake8_pyi::rules::type_comment_in_stub(&mut diagnostics, locator, indexer); } diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index b8fa9c151035a..cc909a087fee3 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -257,6 +257,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "E2515") => (RuleGroup::Stable, rules::pylint::rules::InvalidCharacterZeroWidthSpace), (Pylint, "R0124") => (RuleGroup::Stable, rules::pylint::rules::ComparisonWithItself), (Pylint, "R0133") => (RuleGroup::Stable, rules::pylint::rules::ComparisonOfConstant), + (Pylint, "R0202") => (RuleGroup::Preview, rules::pylint::rules::NoClassmethodDecorator), + (Pylint, "R0203") => (RuleGroup::Preview, rules::pylint::rules::NoStaticmethodDecorator), (Pylint, "R0206") => (RuleGroup::Stable, rules::pylint::rules::PropertyWithParameters), (Pylint, "R0402") => (RuleGroup::Stable, rules::pylint::rules::ManualFromImport), (Pylint, "R0911") => (RuleGroup::Stable, rules::pylint::rules::TooManyReturnStatements), @@ -264,12 +266,15 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "R0913") => (RuleGroup::Stable, rules::pylint::rules::TooManyArguments), (Pylint, "R0915") => (RuleGroup::Stable, rules::pylint::rules::TooManyStatements), (Pylint, "R0916") => (RuleGroup::Preview, rules::pylint::rules::TooManyBooleanExpressions), + (Pylint, "R0917") => (RuleGroup::Preview, rules::pylint::rules::TooManyPositional), (Pylint, "R1701") => (RuleGroup::Stable, rules::pylint::rules::RepeatedIsinstanceCalls), (Pylint, "R1704") => (RuleGroup::Preview, rules::pylint::rules::RedefinedArgumentFromLocal), (Pylint, "R1711") => (RuleGroup::Stable, rules::pylint::rules::UselessReturn), (Pylint, "R1714") => (RuleGroup::Stable, rules::pylint::rules::RepeatedEqualityComparison), (Pylint, "R1706") => (RuleGroup::Preview, rules::pylint::rules::AndOrTernary), (Pylint, "R1722") => (RuleGroup::Stable, rules::pylint::rules::SysExitAlias), + (Pylint, "R1733") => (RuleGroup::Preview, rules::pylint::rules::UnnecessaryDictIndexLookup), + (Pylint, "R1736") => (RuleGroup::Preview, rules::pylint::rules::UnnecessaryListIndexLookup), (Pylint, "R2004") => (RuleGroup::Stable, rules::pylint::rules::MagicValueComparison), (Pylint, "R5501") => (RuleGroup::Stable, rules::pylint::rules::CollapsibleElseIf), (Pylint, "R6201") => (RuleGroup::Preview, rules::pylint::rules::LiteralMembership), @@ -607,6 +612,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Bandit, "112") => (RuleGroup::Stable, rules::flake8_bandit::rules::TryExceptContinue), (Flake8Bandit, "113") => (RuleGroup::Stable, rules::flake8_bandit::rules::RequestWithoutTimeout), (Flake8Bandit, "201") => (RuleGroup::Preview, rules::flake8_bandit::rules::FlaskDebugTrue), + (Flake8Bandit, "202") => (RuleGroup::Preview, rules::flake8_bandit::rules::TarfileUnsafeMembers), (Flake8Bandit, "301") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousPickleUsage), (Flake8Bandit, "302") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousMarshalUsage), (Flake8Bandit, "303") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousInsecureHashUsage), @@ -644,6 +650,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Bandit, "607") => (RuleGroup::Stable, rules::flake8_bandit::rules::StartProcessWithPartialPath), (Flake8Bandit, "608") => (RuleGroup::Stable, rules::flake8_bandit::rules::HardcodedSQLExpression), (Flake8Bandit, "609") => (RuleGroup::Stable, rules::flake8_bandit::rules::UnixCommandWildcardInjection), + (Flake8Bandit, "611") => (RuleGroup::Preview, rules::flake8_bandit::rules::DjangoRawSql), (Flake8Bandit, "612") => (RuleGroup::Stable, rules::flake8_bandit::rules::LoggingConfigInsecureListen), (Flake8Bandit, "701") => (RuleGroup::Stable, rules::flake8_bandit::rules::Jinja2AutoescapeFalse), (Flake8Bandit, "702") => (RuleGroup::Preview, rules::flake8_bandit::rules::MakoTemplates), @@ -965,10 +972,12 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Refurb, "145") => (RuleGroup::Preview, rules::refurb::rules::SliceCopy), (Refurb, "148") => (RuleGroup::Preview, rules::refurb::rules::UnnecessaryEnumerate), (Refurb, "152") => (RuleGroup::Preview, rules::refurb::rules::MathConstant), + (Refurb, "163") => (RuleGroup::Preview, rules::refurb::rules::RedundantLogBase), (Refurb, "168") => (RuleGroup::Preview, rules::refurb::rules::IsinstanceTypeNone), (Refurb, "169") => (RuleGroup::Preview, rules::refurb::rules::TypeNoneComparison), (Refurb, "171") => (RuleGroup::Preview, rules::refurb::rules::SingleItemMembershipTest), (Refurb, "177") => (RuleGroup::Preview, rules::refurb::rules::ImplicitCwd), + (Refurb, "181") => (RuleGroup::Preview, rules::refurb::rules::HashlibDigestHex), // flake8-logging (Flake8Logging, "001") => (RuleGroup::Preview, rules::flake8_logging::rules::DirectLoggerInstantiation), diff --git a/crates/ruff_linter/src/cst/matchers.rs b/crates/ruff_linter/src/cst/matchers.rs index fac3be1e41010..3bce354cb60b8 100644 --- a/crates/ruff_linter/src/cst/matchers.rs +++ b/crates/ruff_linter/src/cst/matchers.rs @@ -1,9 +1,10 @@ use crate::fix::codemods::CodegenStylist; use anyhow::{bail, Result}; use libcst_native::{ - Arg, Attribute, Call, Comparison, CompoundStatement, Dict, Expression, FunctionDef, - GeneratorExp, If, Import, ImportAlias, ImportFrom, ImportNames, IndentedBlock, Lambda, - ListComp, Module, Name, SmallStatement, Statement, Suite, Tuple, With, + Arg, Attribute, Call, Comparison, CompoundStatement, Dict, Expression, FormattedString, + FormattedStringContent, FormattedStringExpression, FunctionDef, GeneratorExp, If, Import, + ImportAlias, ImportFrom, ImportNames, IndentedBlock, Lambda, ListComp, Module, Name, + SmallStatement, Statement, Suite, Tuple, With, }; use ruff_python_codegen::Stylist; @@ -153,6 +154,28 @@ pub(crate) fn match_lambda<'a, 'b>(expression: &'a Expression<'b>) -> Result<&'a } } +pub(crate) fn match_formatted_string<'a, 'b>( + expression: &'a mut Expression<'b>, +) -> Result<&'a mut FormattedString<'b>> { + if let Expression::FormattedString(formatted_string) = expression { + Ok(formatted_string) + } else { + bail!("Expected Expression::FormattedString"); + } +} + +pub(crate) fn match_formatted_string_expression<'a, 'b>( + formatted_string_content: &'a mut FormattedStringContent<'b>, +) -> Result<&'a mut FormattedStringExpression<'b>> { + if let FormattedStringContent::Expression(formatted_string_expression) = + formatted_string_content + { + Ok(formatted_string_expression) + } else { + bail!("Expected FormattedStringContent::Expression") + } +} + pub(crate) fn match_function_def<'a, 'b>( statement: &'a mut Statement<'b>, ) -> Result<&'a mut FunctionDef<'b>> { diff --git a/crates/ruff_linter/src/fix/edits.rs b/crates/ruff_linter/src/fix/edits.rs index 76257f7f5967b..89d6db3f39d38 100644 --- a/crates/ruff_linter/src/fix/edits.rs +++ b/crates/ruff_linter/src/fix/edits.rs @@ -3,12 +3,14 @@ use anyhow::{Context, Result}; use ruff_diagnostics::Edit; -use ruff_python_ast::AnyNodeRef; +use ruff_python_ast::parenthesize::parenthesized_range; use ruff_python_ast::{self as ast, Arguments, ExceptHandler, Stmt}; +use ruff_python_ast::{AnyNodeRef, ArgOrKeyword}; use ruff_python_codegen::Stylist; use ruff_python_index::Indexer; use ruff_python_trivia::{ - has_leading_content, is_python_whitespace, PythonWhitespace, SimpleTokenKind, SimpleTokenizer, + has_leading_content, is_python_whitespace, CommentRanges, PythonWhitespace, SimpleTokenKind, + SimpleTokenizer, }; use ruff_source_file::{Locator, NewlineWithTrailingNewline, UniversalNewlines}; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; @@ -138,6 +140,32 @@ pub(crate) fn remove_argument( } } +/// Generic function to add arguments or keyword arguments to function calls. +pub(crate) fn add_argument( + argument: &str, + arguments: &Arguments, + comment_ranges: &CommentRanges, + source: &str, +) -> Edit { + if let Some(last) = arguments.arguments_source_order().last() { + // Case 1: existing arguments, so append after the last argument. + let last = parenthesized_range( + match last { + ArgOrKeyword::Arg(arg) => arg.into(), + ArgOrKeyword::Keyword(keyword) => (&keyword.value).into(), + }, + arguments.into(), + comment_ranges, + source, + ) + .unwrap_or(last.range()); + Edit::insertion(format!(", {argument}"), last.end()) + } else { + // Case 2: no arguments. Add argument, without any trailing comma. + Edit::insertion(argument.to_string(), arguments.start() + TextSize::from(1)) + } +} + /// Determine if a vector contains only one, specific element. fn is_only(vec: &[T], value: &T) -> bool { vec.len() == 1 && vec[0] == *value diff --git a/crates/ruff_linter/src/linter.rs b/crates/ruff_linter/src/linter.rs index 328c6142aeb40..f6382e8b30349 100644 --- a/crates/ruff_linter/src/linter.rs +++ b/crates/ruff_linter/src/linter.rs @@ -9,6 +9,7 @@ use log::error; use rustc_hash::FxHashMap; use ruff_diagnostics::Diagnostic; +use ruff_notebook::Notebook; use ruff_python_ast::imports::ImportMap; use ruff_python_ast::PySourceType; use ruff_python_codegen::Stylist; @@ -107,7 +108,8 @@ pub fn check_path( locator, indexer, settings, - source_type.is_stub(), + source_type, + source_kind.as_ipy_notebook().map(Notebook::cell_offsets), )); } @@ -149,6 +151,7 @@ pub fn check_path( source_type.is_ipynb(), ) { Ok(python_ast) => { + let cell_offsets = source_kind.as_ipy_notebook().map(Notebook::cell_offsets); if use_ast { diagnostics.extend(check_ast( &python_ast, @@ -161,6 +164,7 @@ pub fn check_path( path, package, source_type, + cell_offsets, )); } if use_imports { @@ -173,8 +177,8 @@ pub fn check_path( stylist, path, package, - source_kind, source_type, + cell_offsets, ); imports = module_imports; diagnostics.extend(import_diagnostics); diff --git a/crates/ruff_linter/src/message/mod.rs b/crates/ruff_linter/src/message/mod.rs index 69f7241b04099..2f44de44eda71 100644 --- a/crates/ruff_linter/src/message/mod.rs +++ b/crates/ruff_linter/src/message/mod.rs @@ -17,6 +17,7 @@ use ruff_diagnostics::{Diagnostic, DiagnosticKind, Fix}; use ruff_notebook::NotebookIndex; use ruff_source_file::{SourceFile, SourceLocation}; use ruff_text_size::{Ranged, TextRange, TextSize}; +pub use sarif::SarifEmitter; pub use text::TextEmitter; mod azure; @@ -28,6 +29,7 @@ mod json; mod json_lines; mod junit; mod pylint; +mod sarif; mod text; #[derive(Debug, PartialEq, Eq)] diff --git a/crates/ruff_linter/src/message/sarif.rs b/crates/ruff_linter/src/message/sarif.rs new file mode 100644 index 0000000000000..3517c0eee335a --- /dev/null +++ b/crates/ruff_linter/src/message/sarif.rs @@ -0,0 +1,212 @@ +use std::io::Write; + +use anyhow::Result; +use serde::{Serialize, Serializer}; +use serde_json::json; + +use ruff_source_file::OneIndexed; + +use crate::codes::Rule; +use crate::fs::normalize_path; +use crate::message::{Emitter, EmitterContext, Message}; +use crate::registry::{AsRule, Linter, RuleNamespace}; +use crate::VERSION; + +use strum::IntoEnumIterator; + +pub struct SarifEmitter; + +impl Emitter for SarifEmitter { + fn emit( + &mut self, + writer: &mut dyn Write, + messages: &[Message], + _context: &EmitterContext, + ) -> Result<()> { + let results = messages + .iter() + .map(SarifResult::from_message) + .collect::>>()?; + + let output = json!({ + "$schema": "https://json.schemastore.org/sarif-2.1.0.json", + "version": "2.1.0", + "runs": [{ + "tool": { + "driver": { + "name": "ruff", + "informationUri": "https://github.com/astral-sh/ruff", + "rules": Rule::iter().map(SarifRule::from).collect::>(), + "version": VERSION.to_string(), + } + }, + "results": results, + }], + }); + serde_json::to_writer_pretty(writer, &output)?; + Ok(()) + } +} + +#[derive(Debug, Clone)] +struct SarifRule<'a> { + name: &'a str, + code: String, + linter: &'a str, + summary: &'a str, + explanation: Option<&'a str>, + url: Option, +} + +impl From for SarifRule<'_> { + fn from(rule: Rule) -> Self { + let code = rule.noqa_code().to_string(); + let (linter, _) = Linter::parse_code(&code).unwrap(); + Self { + name: rule.into(), + code, + linter: linter.name(), + summary: rule.message_formats()[0], + explanation: rule.explanation(), + url: rule.url(), + } + } +} + +impl Serialize for SarifRule<'_> { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + json!({ + "id": self.code, + "shortDescription": { + "text": self.summary, + }, + "fullDescription": { + "text": self.explanation, + }, + "help": { + "text": self.summary, + }, + "helpUri": self.url, + "properties": { + "id": self.code, + "kind": self.linter, + "name": self.name, + "problem.severity": "error".to_string(), + }, + }) + .serialize(serializer) + } +} + +#[derive(Debug)] +struct SarifResult { + rule: Rule, + level: String, + message: String, + uri: String, + start_line: OneIndexed, + start_column: OneIndexed, + end_line: OneIndexed, + end_column: OneIndexed, +} + +impl SarifResult { + #[cfg(not(target_arch = "wasm32"))] + fn from_message(message: &Message) -> Result { + let start_location = message.compute_start_location(); + let end_location = message.compute_end_location(); + let path = normalize_path(message.filename()); + Ok(Self { + rule: message.kind.rule(), + level: "error".to_string(), + message: message.kind.name.clone(), + uri: url::Url::from_file_path(&path) + .map_err(|()| anyhow::anyhow!("Failed to convert path to URL: {}", path.display()))? + .to_string(), + start_line: start_location.row, + start_column: start_location.column, + end_line: end_location.row, + end_column: end_location.column, + }) + } + + #[cfg(target_arch = "wasm32")] + #[allow(clippy::unnecessary_wraps)] + fn from_message(message: &Message) -> Result { + let start_location = message.compute_start_location(); + let end_location = message.compute_end_location(); + let path = normalize_path(message.filename()); + Ok(Self { + rule: message.kind.rule(), + level: "error".to_string(), + message: message.kind.name.clone(), + uri: path.display().to_string(), + start_line: start_location.row, + start_column: start_location.column, + end_line: end_location.row, + end_column: end_location.column, + }) + } +} + +impl Serialize for SarifResult { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + json!({ + "level": self.level, + "message": { + "text": self.message, + }, + "locations": [{ + "physicalLocation": { + "artifactLocation": { + "uri": self.uri, + }, + "region": { + "startLine": self.start_line, + "startColumn": self.start_column, + "endLine": self.end_line, + "endColumn": self.end_column, + } + } + }], + "ruleId": self.rule.noqa_code().to_string(), + }) + .serialize(serializer) + } +} + +#[cfg(test)] +mod tests { + + use crate::message::tests::{capture_emitter_output, create_messages}; + use crate::message::SarifEmitter; + + fn get_output() -> String { + let mut emitter = SarifEmitter {}; + capture_emitter_output(&mut emitter, &create_messages()) + } + + #[test] + fn valid_json() { + let content = get_output(); + serde_json::from_str::(&content).unwrap(); + } + + #[test] + fn test_results() { + let content = get_output(); + let sarif = serde_json::from_str::(content.as_str()).unwrap(); + let rules = sarif["runs"][0]["tool"]["driver"]["rules"] + .as_array() + .unwrap(); + let results = sarif["runs"][0]["results"].as_array().unwrap(); + assert_eq!(results.len(), 3); + assert!(rules.len() > 3); + } +} diff --git a/crates/ruff_linter/src/registry.rs b/crates/ruff_linter/src/registry.rs index 9a81a5630a12b..a9a2c400c27e7 100644 --- a/crates/ruff_linter/src/registry.rs +++ b/crates/ruff_linter/src/registry.rs @@ -297,7 +297,6 @@ impl Rule { | Rule::TabIndentation | Rule::TrailingCommaOnBareTuple | Rule::TypeCommentInStub - | Rule::UnicodeKindPrefix | Rule::UselessSemicolon | Rule::UTF8EncodingDeclaration => LintSource::Tokens, Rule::IOError => LintSource::Io, diff --git a/crates/ruff_linter/src/rules/airflow/rules/task_variable_name.rs b/crates/ruff_linter/src/rules/airflow/rules/task_variable_name.rs index dec0a953081fb..76ebb405a225d 100644 --- a/crates/ruff_linter/src/rules/airflow/rules/task_variable_name.rs +++ b/crates/ruff_linter/src/rules/airflow/rules/task_variable_name.rs @@ -81,7 +81,7 @@ pub(crate) fn variable_name_task_id( let ast::ExprStringLiteral { value: task_id, .. } = keyword.value.as_string_literal_expr()?; // If the target name is the same as the task_id, no violation. - if id == task_id { + if task_id == id { return None; } diff --git a/crates/ruff_linter/src/rules/flake8_annotations/helpers.rs b/crates/ruff_linter/src/rules/flake8_annotations/helpers.rs index 318ebf053fac9..41cff286d79c5 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_annotations/helpers.rs @@ -1,13 +1,18 @@ use itertools::Itertools; +use rustc_hash::FxHashSet; -use ruff_python_ast::helpers::{pep_604_union, ReturnStatementVisitor}; +use ruff_diagnostics::Edit; +use ruff_python_ast::helpers::{ + implicit_return, pep_604_union, typing_optional, typing_union, ReturnStatementVisitor, +}; use ruff_python_ast::visitor::Visitor; use ruff_python_ast::{self as ast, Expr, ExprContext}; use ruff_python_semantic::analyze::type_inference::{NumberLike, PythonType, ResolvedPythonType}; use ruff_python_semantic::analyze::visibility; use ruff_python_semantic::{Definition, SemanticModel}; -use ruff_text_size::TextRange; +use ruff_text_size::{TextRange, TextSize}; +use crate::importer::{ImportRequest, Importer}; use crate::settings::types::PythonVersion; /// Return the name of the function, if it's overloaded. @@ -38,22 +43,24 @@ pub(crate) fn is_overload_impl( } /// Given a function, guess its return type. -pub(crate) fn auto_return_type( - function: &ast::StmtFunctionDef, - target_version: PythonVersion, -) -> Option { +pub(crate) fn auto_return_type(function: &ast::StmtFunctionDef) -> Option { // Collect all the `return` statements. let returns = { let mut visitor = ReturnStatementVisitor::default(); visitor.visit_body(&function.body); + + // Ignore generators. if visitor.is_generator { return None; } + visitor.returns }; // Determine the return type of the first `return` statement. - let (return_statement, returns) = returns.split_first()?; + let Some((return_statement, returns)) = returns.split_first() else { + return Some(AutoPythonType::Atom(PythonType::None)); + }; let mut return_type = return_statement.value.as_deref().map_or( ResolvedPythonType::Atom(PythonType::None), ResolvedPythonType::from, @@ -67,25 +74,105 @@ pub(crate) fn auto_return_type( )); } + // If the function has an implicit return, union with `None`, as in: + // ```python + // def func(x: int): + // if x > 0: + // return 1 + // ``` + if implicit_return(function) { + return_type = return_type.union(ResolvedPythonType::Atom(PythonType::None)); + } + match return_type { - ResolvedPythonType::Atom(python_type) => type_expr(python_type), - ResolvedPythonType::Union(python_types) if target_version >= PythonVersion::Py310 => { - // Aggregate all the individual types (e.g., `int`, `float`). - let names = python_types - .iter() - .sorted_unstable() - .filter_map(|python_type| type_expr(*python_type)) - .collect::>(); - - // Wrap in a bitwise union (e.g., `int | float`). - Some(pep_604_union(&names)) - } - ResolvedPythonType::Union(_) => None, + ResolvedPythonType::Atom(python_type) => Some(AutoPythonType::Atom(python_type)), + ResolvedPythonType::Union(python_types) => Some(AutoPythonType::Union(python_types)), ResolvedPythonType::Unknown => None, ResolvedPythonType::TypeError => None, } } +#[derive(Debug)] +pub(crate) enum AutoPythonType { + Atom(PythonType), + Union(FxHashSet), +} + +impl AutoPythonType { + /// Convert an [`AutoPythonType`] into an [`Expr`]. + /// + /// If the [`Expr`] relies on importing any external symbols, those imports will be returned as + /// additional edits. + pub(crate) fn into_expression( + self, + importer: &Importer, + at: TextSize, + semantic: &SemanticModel, + target_version: PythonVersion, + ) -> Option<(Expr, Vec)> { + match self { + AutoPythonType::Atom(python_type) => { + let expr = type_expr(python_type)?; + Some((expr, vec![])) + } + AutoPythonType::Union(python_types) => { + if target_version >= PythonVersion::Py310 { + // Aggregate all the individual types (e.g., `int`, `float`). + let names = python_types + .iter() + .sorted_unstable() + .map(|python_type| type_expr(*python_type)) + .collect::>>()?; + + // Wrap in a bitwise union (e.g., `int | float`). + let expr = pep_604_union(&names); + + Some((expr, vec![])) + } else { + let python_types = python_types + .into_iter() + .sorted_unstable() + .collect::>(); + + match python_types.as_slice() { + [python_type, PythonType::None] | [PythonType::None, python_type] => { + let element = type_expr(*python_type)?; + + // Ex) `Optional[int]` + let (optional_edit, binding) = importer + .get_or_import_symbol( + &ImportRequest::import_from("typing", "Optional"), + at, + semantic, + ) + .ok()?; + let expr = typing_optional(element, binding); + Some((expr, vec![optional_edit])) + } + _ => { + let elements = python_types + .into_iter() + .map(type_expr) + .collect::>>()?; + + // Ex) `Union[int, str]` + let (union_edit, binding) = importer + .get_or_import_symbol( + &ImportRequest::import_from("typing", "Union"), + at, + semantic, + ) + .ok()?; + let expr = typing_union(&elements, binding); + Some((expr, vec![union_edit])) + } + } + } + } + } + } +} + /// Given a [`PythonType`], return an [`Expr`] that resolves to that type. fn type_expr(python_type: PythonType) -> Option { fn name(name: &str) -> Expr { diff --git a/crates/ruff_linter/src/rules/flake8_annotations/mod.rs b/crates/ruff_linter/src/rules/flake8_annotations/mod.rs index b7dbf012035aa..859f8588c5311 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_annotations/mod.rs @@ -11,6 +11,7 @@ mod tests { use crate::assert_messages; use crate::registry::Rule; + use crate::settings::types::PythonVersion; use crate::settings::LinterSettings; use crate::test::test_path; @@ -128,6 +129,25 @@ mod tests { Ok(()) } + #[test] + fn auto_return_type_py38() -> Result<()> { + let diagnostics = test_path( + Path::new("flake8_annotations/auto_return_type.py"), + &LinterSettings { + target_version: PythonVersion::Py38, + ..LinterSettings::for_rules(vec![ + Rule::MissingReturnTypeUndocumentedPublicFunction, + Rule::MissingReturnTypePrivateFunction, + Rule::MissingReturnTypeSpecialMethod, + Rule::MissingReturnTypeStaticMethod, + Rule::MissingReturnTypeClassMethod, + ]) + }, + )?; + assert_messages!(diagnostics); + Ok(()) + } + #[test] fn suppress_none_returning() -> Result<()> { let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs b/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs index 3fe862c01991d..dee00d6667831 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs +++ b/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs @@ -505,15 +505,10 @@ fn check_dynamically_typed( ) where F: FnOnce() -> String, { - if let Expr::StringLiteral(ast::ExprStringLiteral { - range, - value: string, - .. - }) = annotation - { + if let Expr::StringLiteral(ast::ExprStringLiteral { range, value }) = annotation { // Quoted annotations if let Ok((parsed_annotation, _)) = - parse_type_annotation(string, *range, checker.locator().contents()) + parse_type_annotation(value.to_str(), *range, checker.locator().contents()) { if type_hint_resolves_to_any( &parsed_annotation, @@ -542,6 +537,19 @@ fn check_dynamically_typed( } } +fn is_empty_body(body: &[Stmt]) -> bool { + body.iter().all(|stmt| match stmt { + Stmt::Pass(_) => true, + Stmt::Expr(ast::StmtExpr { value, range: _ }) => { + matches!( + value.as_ref(), + Expr::StringLiteral(_) | Expr::EllipsisLiteral(_) + ) + } + _ => false, + }) +} + /// Generate flake8-annotation checks for a given `Definition`. pub(crate) fn definition( checker: &Checker, @@ -730,39 +738,67 @@ pub(crate) fn definition( ) { if is_method && visibility::is_classmethod(decorator_list, checker.semantic()) { if checker.enabled(Rule::MissingReturnTypeClassMethod) { - let return_type = auto_return_type(function, checker.settings.target_version) - .map(|return_type| checker.generator().expr(&return_type)); + let return_type = if visibility::is_abstract(decorator_list, checker.semantic()) + && is_empty_body(body) + { + None + } else { + auto_return_type(function) + .and_then(|return_type| { + return_type.into_expression( + checker.importer(), + function.parameters.start(), + checker.semantic(), + checker.settings.target_version, + ) + }) + .map(|(return_type, edits)| (checker.generator().expr(&return_type), edits)) + }; let mut diagnostic = Diagnostic::new( MissingReturnTypeClassMethod { name: name.to_string(), - annotation: return_type.clone(), + annotation: return_type.clone().map(|(return_type, ..)| return_type), }, function.identifier(), ); - if let Some(return_type) = return_type { - diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( - format!(" -> {return_type}"), - function.parameters.range().end(), - ))); + if let Some((return_type, edits)) = return_type { + diagnostic.set_fix(Fix::unsafe_edits( + Edit::insertion(format!(" -> {return_type}"), function.parameters.end()), + edits, + )); } diagnostics.push(diagnostic); } } else if is_method && visibility::is_staticmethod(decorator_list, checker.semantic()) { if checker.enabled(Rule::MissingReturnTypeStaticMethod) { - let return_type = auto_return_type(function, checker.settings.target_version) - .map(|return_type| checker.generator().expr(&return_type)); + let return_type = if visibility::is_abstract(decorator_list, checker.semantic()) + && is_empty_body(body) + { + None + } else { + auto_return_type(function) + .and_then(|return_type| { + return_type.into_expression( + checker.importer(), + function.parameters.start(), + checker.semantic(), + checker.settings.target_version, + ) + }) + .map(|(return_type, edits)| (checker.generator().expr(&return_type), edits)) + }; let mut diagnostic = Diagnostic::new( MissingReturnTypeStaticMethod { name: name.to_string(), - annotation: return_type.clone(), + annotation: return_type.clone().map(|(return_type, ..)| return_type), }, function.identifier(), ); - if let Some(return_type) = return_type { - diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( - format!(" -> {return_type}"), - function.parameters.range().end(), - ))); + if let Some((return_type, edits)) = return_type { + diagnostic.set_fix(Fix::unsafe_edits( + Edit::insertion(format!(" -> {return_type}"), function.parameters.end()), + edits, + )); } diagnostics.push(diagnostic); } @@ -780,7 +816,7 @@ pub(crate) fn definition( ); diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( " -> None".to_string(), - function.parameters.range().end(), + function.parameters.end(), ))); diagnostics.push(diagnostic); } @@ -798,7 +834,7 @@ pub(crate) fn definition( if let Some(return_type) = return_type { diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( format!(" -> {return_type}"), - function.parameters.range().end(), + function.parameters.end(), ))); } diagnostics.push(diagnostic); @@ -808,20 +844,41 @@ pub(crate) fn definition( visibility::Visibility::Public => { if checker.enabled(Rule::MissingReturnTypeUndocumentedPublicFunction) { let return_type = - auto_return_type(function, checker.settings.target_version) - .map(|return_type| checker.generator().expr(&return_type)); + if visibility::is_abstract(decorator_list, checker.semantic()) + && is_empty_body(body) + { + None + } else { + auto_return_type(function) + .and_then(|return_type| { + return_type.into_expression( + checker.importer(), + function.parameters.start(), + checker.semantic(), + checker.settings.target_version, + ) + }) + .map(|(return_type, edits)| { + (checker.generator().expr(&return_type), edits) + }) + }; let mut diagnostic = Diagnostic::new( MissingReturnTypeUndocumentedPublicFunction { name: name.to_string(), - annotation: return_type.clone(), + annotation: return_type + .clone() + .map(|(return_type, ..)| return_type), }, function.identifier(), ); - if let Some(return_type) = return_type { - diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( - format!(" -> {return_type}"), - function.parameters.range().end(), - ))); + if let Some((return_type, edits)) = return_type { + diagnostic.set_fix(Fix::unsafe_edits( + Edit::insertion( + format!(" -> {return_type}"), + function.parameters.end(), + ), + edits, + )); } diagnostics.push(diagnostic); } @@ -829,20 +886,41 @@ pub(crate) fn definition( visibility::Visibility::Private => { if checker.enabled(Rule::MissingReturnTypePrivateFunction) { let return_type = - auto_return_type(function, checker.settings.target_version) - .map(|return_type| checker.generator().expr(&return_type)); + if visibility::is_abstract(decorator_list, checker.semantic()) + && is_empty_body(body) + { + None + } else { + auto_return_type(function) + .and_then(|return_type| { + return_type.into_expression( + checker.importer(), + function.parameters.start(), + checker.semantic(), + checker.settings.target_version, + ) + }) + .map(|(return_type, edits)| { + (checker.generator().expr(&return_type), edits) + }) + }; let mut diagnostic = Diagnostic::new( MissingReturnTypePrivateFunction { name: name.to_string(), - annotation: return_type.clone(), + annotation: return_type + .clone() + .map(|(return_type, ..)| return_type), }, function.identifier(), ); - if let Some(return_type) = return_type { - diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( - format!(" -> {return_type}"), - function.parameters.range().end(), - ))); + if let Some((return_type, edits)) = return_type { + diagnostic.set_fix(Fix::unsafe_edits( + Edit::insertion( + format!(" -> {return_type}"), + function.parameters.end(), + ), + edits, + )); } diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__auto_return_type.snap b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__auto_return_type.snap index 108a1483004c7..72b8e8b9a66cc 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__auto_return_type.snap +++ b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__auto_return_type.snap @@ -123,5 +123,376 @@ auto_return_type.py:31:5: ANN201 [*] Missing return type annotation for public f 31 |-def func(x: int): 31 |+def func(x: int) -> str | float: 32 32 | return 1 + 2.5 if x > 0 else 1.5 or "str" +33 33 | +34 34 | + +auto_return_type.py:35:5: ANN201 Missing return type annotation for public function `func` + | +35 | def func(x: int): + | ^^^^ ANN201 +36 | if not x: +37 | return None + | + = help: Add return type annotation + +auto_return_type.py:41:5: ANN201 Missing return type annotation for public function `func` + | +41 | def func(x: int): + | ^^^^ ANN201 +42 | return {"foo": 1} + | + = help: Add return type annotation + +auto_return_type.py:45:5: ANN201 [*] Missing return type annotation for public function `func` + | +45 | def func(x: int): + | ^^^^ ANN201 +46 | if not x: +47 | return 1 + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +42 42 | return {"foo": 1} +43 43 | +44 44 | +45 |-def func(x: int): + 45 |+def func(x: int) -> int: +46 46 | if not x: +47 47 | return 1 +48 48 | else: + +auto_return_type.py:52:5: ANN201 [*] Missing return type annotation for public function `func` + | +52 | def func(x: int): + | ^^^^ ANN201 +53 | if not x: +54 | return 1 + | + = help: Add return type annotation: `int | None` + +ℹ Unsafe fix +49 49 | return True +50 50 | +51 51 | +52 |-def func(x: int): + 52 |+def func(x: int) -> int | None: +53 53 | if not x: +54 54 | return 1 +55 55 | else: + +auto_return_type.py:59:5: ANN201 [*] Missing return type annotation for public function `func` + | +59 | def func(x: int): + | ^^^^ ANN201 +60 | if not x: +61 | return 1 + | + = help: Add return type annotation: `str | int | None` + +ℹ Unsafe fix +56 56 | return None +57 57 | +58 58 | +59 |-def func(x: int): + 59 |+def func(x: int) -> str | int | None: +60 60 | if not x: +61 61 | return 1 +62 62 | elif x > 5: + +auto_return_type.py:68:5: ANN201 [*] Missing return type annotation for public function `func` + | +68 | def func(x: int): + | ^^^^ ANN201 +69 | if x: +70 | return 1 + | + = help: Add return type annotation: `int | None` + +ℹ Unsafe fix +65 65 | return None +66 66 | +67 67 | +68 |-def func(x: int): + 68 |+def func(x: int) -> int | None: +69 69 | if x: +70 70 | return 1 +71 71 | + +auto_return_type.py:73:5: ANN201 [*] Missing return type annotation for public function `func` + | +73 | def func(): + | ^^^^ ANN201 +74 | x = 1 + | + = help: Add return type annotation: `None` + +ℹ Unsafe fix +70 70 | return 1 +71 71 | +72 72 | +73 |-def func(): + 73 |+def func() -> None: +74 74 | x = 1 +75 75 | +76 76 | + +auto_return_type.py:77:5: ANN201 [*] Missing return type annotation for public function `func` + | +77 | def func(x: int): + | ^^^^ ANN201 +78 | if x > 0: +79 | return 1 + | + = help: Add return type annotation: `int | None` + +ℹ Unsafe fix +74 74 | x = 1 +75 75 | +76 76 | +77 |-def func(x: int): + 77 |+def func(x: int) -> int | None: +78 78 | if x > 0: +79 79 | return 1 +80 80 | + +auto_return_type.py:82:5: ANN201 [*] Missing return type annotation for public function `func` + | +82 | def func(x: int): + | ^^^^ ANN201 +83 | match x: +84 | case [1, 2, 3]: + | + = help: Add return type annotation: `str | int` + +ℹ Unsafe fix +79 79 | return 1 +80 80 | +81 81 | +82 |-def func(x: int): + 82 |+def func(x: int) -> str | int: +83 83 | match x: +84 84 | case [1, 2, 3]: +85 85 | return 1 + +auto_return_type.py:90:5: ANN201 [*] Missing return type annotation for public function `func` + | +90 | def func(x: int): + | ^^^^ ANN201 +91 | for i in range(5): +92 | if i > 0: + | + = help: Add return type annotation: `int | None` + +ℹ Unsafe fix +87 87 | return "foo" +88 88 | +89 89 | +90 |-def func(x: int): + 90 |+def func(x: int) -> int | None: +91 91 | for i in range(5): +92 92 | if i > 0: +93 93 | return 1 + +auto_return_type.py:96:5: ANN201 [*] Missing return type annotation for public function `func` + | +96 | def func(x: int): + | ^^^^ ANN201 +97 | for i in range(5): +98 | if i > 0: + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +93 93 | return 1 +94 94 | +95 95 | +96 |-def func(x: int): + 96 |+def func(x: int) -> int: +97 97 | for i in range(5): +98 98 | if i > 0: +99 99 | return 1 + +auto_return_type.py:104:5: ANN201 [*] Missing return type annotation for public function `func` + | +104 | def func(x: int): + | ^^^^ ANN201 +105 | for i in range(5): +106 | if i > 0: + | + = help: Add return type annotation: `int | None` + +ℹ Unsafe fix +101 101 | return 4 +102 102 | +103 103 | +104 |-def func(x: int): + 104 |+def func(x: int) -> int | None: +105 105 | for i in range(5): +106 106 | if i > 0: +107 107 | break + +auto_return_type.py:112:5: ANN201 [*] Missing return type annotation for public function `func` + | +112 | def func(x: int): + | ^^^^ ANN201 +113 | try: +114 | pass + | + = help: Add return type annotation: `int | None` + +ℹ Unsafe fix +109 109 | return 4 +110 110 | +111 111 | +112 |-def func(x: int): + 112 |+def func(x: int) -> int | None: +113 113 | try: +114 114 | pass +115 115 | except: + +auto_return_type.py:119:5: ANN201 [*] Missing return type annotation for public function `func` + | +119 | def func(x: int): + | ^^^^ ANN201 +120 | try: +121 | pass + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +116 116 | return 1 +117 117 | +118 118 | +119 |-def func(x: int): + 119 |+def func(x: int) -> int: +120 120 | try: +121 121 | pass +122 122 | except: + +auto_return_type.py:128:5: ANN201 [*] Missing return type annotation for public function `func` + | +128 | def func(x: int): + | ^^^^ ANN201 +129 | try: +130 | pass + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +125 125 | return 2 +126 126 | +127 127 | +128 |-def func(x: int): + 128 |+def func(x: int) -> int: +129 129 | try: +130 130 | pass +131 131 | except: + +auto_return_type.py:137:5: ANN201 [*] Missing return type annotation for public function `func` + | +137 | def func(x: int): + | ^^^^ ANN201 +138 | try: +139 | return 1 + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +134 134 | return 2 +135 135 | +136 136 | +137 |-def func(x: int): + 137 |+def func(x: int) -> int: +138 138 | try: +139 139 | return 1 +140 140 | except: + +auto_return_type.py:146:5: ANN201 [*] Missing return type annotation for public function `func` + | +146 | def func(x: int): + | ^^^^ ANN201 +147 | while x > 0: +148 | break + | + = help: Add return type annotation: `int | None` + +ℹ Unsafe fix +143 143 | pass +144 144 | +145 145 | +146 |-def func(x: int): + 146 |+def func(x: int) -> int | None: +147 147 | while x > 0: +148 148 | break +149 149 | return 1 + +auto_return_type.py:158:9: ANN201 Missing return type annotation for public function `method` + | +156 | class Foo(abc.ABC): +157 | @abstractmethod +158 | def method(self): + | ^^^^^^ ANN201 +159 | pass + | + = help: Add return type annotation + +auto_return_type.py:162:9: ANN201 Missing return type annotation for public function `method` + | +161 | @abc.abstractmethod +162 | def method(self): + | ^^^^^^ ANN201 +163 | """Docstring.""" + | + = help: Add return type annotation + +auto_return_type.py:166:9: ANN201 Missing return type annotation for public function `method` + | +165 | @abc.abstractmethod +166 | def method(self): + | ^^^^^^ ANN201 +167 | ... + | + = help: Add return type annotation + +auto_return_type.py:171:9: ANN205 Missing return type annotation for staticmethod `method` + | +169 | @staticmethod +170 | @abstractmethod +171 | def method(): + | ^^^^^^ ANN205 +172 | pass + | + = help: Add return type annotation + +auto_return_type.py:176:9: ANN206 Missing return type annotation for classmethod `method` + | +174 | @classmethod +175 | @abstractmethod +176 | def method(cls): + | ^^^^^^ ANN206 +177 | pass + | + = help: Add return type annotation + +auto_return_type.py:180:9: ANN201 [*] Missing return type annotation for public function `method` + | +179 | @abstractmethod +180 | def method(self): + | ^^^^^^ ANN201 +181 | if self.x > 0: +182 | return 1 + | + = help: Add return type annotation: `float` + +ℹ Unsafe fix +177 177 | pass +178 178 | +179 179 | @abstractmethod +180 |- def method(self): + 180 |+ def method(self) -> float: +181 181 | if self.x > 0: +182 182 | return 1 +183 183 | else: diff --git a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__auto_return_type_py38.snap b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__auto_return_type_py38.snap new file mode 100644 index 0000000000000..7667c2299de9e --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__auto_return_type_py38.snap @@ -0,0 +1,553 @@ +--- +source: crates/ruff_linter/src/rules/flake8_annotations/mod.rs +--- +auto_return_type.py:1:5: ANN201 [*] Missing return type annotation for public function `func` + | +1 | def func(): + | ^^^^ ANN201 +2 | return 1 + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +1 |-def func(): + 1 |+def func() -> int: +2 2 | return 1 +3 3 | +4 4 | + +auto_return_type.py:5:5: ANN201 [*] Missing return type annotation for public function `func` + | +5 | def func(): + | ^^^^ ANN201 +6 | return 1.5 + | + = help: Add return type annotation: `float` + +ℹ Unsafe fix +2 2 | return 1 +3 3 | +4 4 | +5 |-def func(): + 5 |+def func() -> float: +6 6 | return 1.5 +7 7 | +8 8 | + +auto_return_type.py:9:5: ANN201 [*] Missing return type annotation for public function `func` + | + 9 | def func(x: int): + | ^^^^ ANN201 +10 | if x > 0: +11 | return 1 + | + = help: Add return type annotation: `float` + +ℹ Unsafe fix +6 6 | return 1.5 +7 7 | +8 8 | +9 |-def func(x: int): + 9 |+def func(x: int) -> float: +10 10 | if x > 0: +11 11 | return 1 +12 12 | else: + +auto_return_type.py:16:5: ANN201 [*] Missing return type annotation for public function `func` + | +16 | def func(): + | ^^^^ ANN201 +17 | return True + | + = help: Add return type annotation: `bool` + +ℹ Unsafe fix +13 13 | return 1.5 +14 14 | +15 15 | +16 |-def func(): + 16 |+def func() -> bool: +17 17 | return True +18 18 | +19 19 | + +auto_return_type.py:20:5: ANN201 [*] Missing return type annotation for public function `func` + | +20 | def func(x: int): + | ^^^^ ANN201 +21 | if x > 0: +22 | return None + | + = help: Add return type annotation: `None` + +ℹ Unsafe fix +17 17 | return True +18 18 | +19 19 | +20 |-def func(x: int): + 20 |+def func(x: int) -> None: +21 21 | if x > 0: +22 22 | return None +23 23 | else: + +auto_return_type.py:27:5: ANN201 [*] Missing return type annotation for public function `func` + | +27 | def func(x: int): + | ^^^^ ANN201 +28 | return 1 or 2.5 if x > 0 else 1.5 or "str" + | + = help: Add return type annotation: `Union[str | float]` + +ℹ Unsafe fix + 1 |+from typing import Union +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +24 25 | return +25 26 | +26 27 | +27 |-def func(x: int): + 28 |+def func(x: int) -> Union[str | float]: +28 29 | return 1 or 2.5 if x > 0 else 1.5 or "str" +29 30 | +30 31 | + +auto_return_type.py:31:5: ANN201 [*] Missing return type annotation for public function `func` + | +31 | def func(x: int): + | ^^^^ ANN201 +32 | return 1 + 2.5 if x > 0 else 1.5 or "str" + | + = help: Add return type annotation: `Union[str | float]` + +ℹ Unsafe fix + 1 |+from typing import Union +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +28 29 | return 1 or 2.5 if x > 0 else 1.5 or "str" +29 30 | +30 31 | +31 |-def func(x: int): + 32 |+def func(x: int) -> Union[str | float]: +32 33 | return 1 + 2.5 if x > 0 else 1.5 or "str" +33 34 | +34 35 | + +auto_return_type.py:35:5: ANN201 Missing return type annotation for public function `func` + | +35 | def func(x: int): + | ^^^^ ANN201 +36 | if not x: +37 | return None + | + = help: Add return type annotation + +auto_return_type.py:41:5: ANN201 Missing return type annotation for public function `func` + | +41 | def func(x: int): + | ^^^^ ANN201 +42 | return {"foo": 1} + | + = help: Add return type annotation + +auto_return_type.py:45:5: ANN201 [*] Missing return type annotation for public function `func` + | +45 | def func(x: int): + | ^^^^ ANN201 +46 | if not x: +47 | return 1 + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +42 42 | return {"foo": 1} +43 43 | +44 44 | +45 |-def func(x: int): + 45 |+def func(x: int) -> int: +46 46 | if not x: +47 47 | return 1 +48 48 | else: + +auto_return_type.py:52:5: ANN201 [*] Missing return type annotation for public function `func` + | +52 | def func(x: int): + | ^^^^ ANN201 +53 | if not x: +54 | return 1 + | + = help: Add return type annotation: `Optional[int]` + +ℹ Unsafe fix + 1 |+from typing import Optional +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +49 50 | return True +50 51 | +51 52 | +52 |-def func(x: int): + 53 |+def func(x: int) -> Optional[int]: +53 54 | if not x: +54 55 | return 1 +55 56 | else: + +auto_return_type.py:59:5: ANN201 [*] Missing return type annotation for public function `func` + | +59 | def func(x: int): + | ^^^^ ANN201 +60 | if not x: +61 | return 1 + | + = help: Add return type annotation: `Union[str | int | None]` + +ℹ Unsafe fix + 1 |+from typing import Union +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +56 57 | return None +57 58 | +58 59 | +59 |-def func(x: int): + 60 |+def func(x: int) -> Union[str | int | None]: +60 61 | if not x: +61 62 | return 1 +62 63 | elif x > 5: + +auto_return_type.py:68:5: ANN201 [*] Missing return type annotation for public function `func` + | +68 | def func(x: int): + | ^^^^ ANN201 +69 | if x: +70 | return 1 + | + = help: Add return type annotation: `Optional[int]` + +ℹ Unsafe fix + 1 |+from typing import Optional +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +65 66 | return None +66 67 | +67 68 | +68 |-def func(x: int): + 69 |+def func(x: int) -> Optional[int]: +69 70 | if x: +70 71 | return 1 +71 72 | + +auto_return_type.py:73:5: ANN201 [*] Missing return type annotation for public function `func` + | +73 | def func(): + | ^^^^ ANN201 +74 | x = 1 + | + = help: Add return type annotation: `None` + +ℹ Unsafe fix +70 70 | return 1 +71 71 | +72 72 | +73 |-def func(): + 73 |+def func() -> None: +74 74 | x = 1 +75 75 | +76 76 | + +auto_return_type.py:77:5: ANN201 [*] Missing return type annotation for public function `func` + | +77 | def func(x: int): + | ^^^^ ANN201 +78 | if x > 0: +79 | return 1 + | + = help: Add return type annotation: `Optional[int]` + +ℹ Unsafe fix + 1 |+from typing import Optional +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +74 75 | x = 1 +75 76 | +76 77 | +77 |-def func(x: int): + 78 |+def func(x: int) -> Optional[int]: +78 79 | if x > 0: +79 80 | return 1 +80 81 | + +auto_return_type.py:82:5: ANN201 [*] Missing return type annotation for public function `func` + | +82 | def func(x: int): + | ^^^^ ANN201 +83 | match x: +84 | case [1, 2, 3]: + | + = help: Add return type annotation: `Union[str | int]` + +ℹ Unsafe fix + 1 |+from typing import Union +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +79 80 | return 1 +80 81 | +81 82 | +82 |-def func(x: int): + 83 |+def func(x: int) -> Union[str | int]: +83 84 | match x: +84 85 | case [1, 2, 3]: +85 86 | return 1 + +auto_return_type.py:90:5: ANN201 [*] Missing return type annotation for public function `func` + | +90 | def func(x: int): + | ^^^^ ANN201 +91 | for i in range(5): +92 | if i > 0: + | + = help: Add return type annotation: `Optional[int]` + +ℹ Unsafe fix + 1 |+from typing import Optional +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +87 88 | return "foo" +88 89 | +89 90 | +90 |-def func(x: int): + 91 |+def func(x: int) -> Optional[int]: +91 92 | for i in range(5): +92 93 | if i > 0: +93 94 | return 1 + +auto_return_type.py:96:5: ANN201 [*] Missing return type annotation for public function `func` + | +96 | def func(x: int): + | ^^^^ ANN201 +97 | for i in range(5): +98 | if i > 0: + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +93 93 | return 1 +94 94 | +95 95 | +96 |-def func(x: int): + 96 |+def func(x: int) -> int: +97 97 | for i in range(5): +98 98 | if i > 0: +99 99 | return 1 + +auto_return_type.py:104:5: ANN201 [*] Missing return type annotation for public function `func` + | +104 | def func(x: int): + | ^^^^ ANN201 +105 | for i in range(5): +106 | if i > 0: + | + = help: Add return type annotation: `Optional[int]` + +ℹ Unsafe fix + 1 |+from typing import Optional +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +101 102 | return 4 +102 103 | +103 104 | +104 |-def func(x: int): + 105 |+def func(x: int) -> Optional[int]: +105 106 | for i in range(5): +106 107 | if i > 0: +107 108 | break + +auto_return_type.py:112:5: ANN201 [*] Missing return type annotation for public function `func` + | +112 | def func(x: int): + | ^^^^ ANN201 +113 | try: +114 | pass + | + = help: Add return type annotation: `Optional[int]` + +ℹ Unsafe fix + 1 |+from typing import Optional +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +109 110 | return 4 +110 111 | +111 112 | +112 |-def func(x: int): + 113 |+def func(x: int) -> Optional[int]: +113 114 | try: +114 115 | pass +115 116 | except: + +auto_return_type.py:119:5: ANN201 [*] Missing return type annotation for public function `func` + | +119 | def func(x: int): + | ^^^^ ANN201 +120 | try: +121 | pass + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +116 116 | return 1 +117 117 | +118 118 | +119 |-def func(x: int): + 119 |+def func(x: int) -> int: +120 120 | try: +121 121 | pass +122 122 | except: + +auto_return_type.py:128:5: ANN201 [*] Missing return type annotation for public function `func` + | +128 | def func(x: int): + | ^^^^ ANN201 +129 | try: +130 | pass + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +125 125 | return 2 +126 126 | +127 127 | +128 |-def func(x: int): + 128 |+def func(x: int) -> int: +129 129 | try: +130 130 | pass +131 131 | except: + +auto_return_type.py:137:5: ANN201 [*] Missing return type annotation for public function `func` + | +137 | def func(x: int): + | ^^^^ ANN201 +138 | try: +139 | return 1 + | + = help: Add return type annotation: `int` + +ℹ Unsafe fix +134 134 | return 2 +135 135 | +136 136 | +137 |-def func(x: int): + 137 |+def func(x: int) -> int: +138 138 | try: +139 139 | return 1 +140 140 | except: + +auto_return_type.py:146:5: ANN201 [*] Missing return type annotation for public function `func` + | +146 | def func(x: int): + | ^^^^ ANN201 +147 | while x > 0: +148 | break + | + = help: Add return type annotation: `Optional[int]` + +ℹ Unsafe fix + 1 |+from typing import Optional +1 2 | def func(): +2 3 | return 1 +3 4 | +-------------------------------------------------------------------------------- +143 144 | pass +144 145 | +145 146 | +146 |-def func(x: int): + 147 |+def func(x: int) -> Optional[int]: +147 148 | while x > 0: +148 149 | break +149 150 | return 1 + +auto_return_type.py:158:9: ANN201 Missing return type annotation for public function `method` + | +156 | class Foo(abc.ABC): +157 | @abstractmethod +158 | def method(self): + | ^^^^^^ ANN201 +159 | pass + | + = help: Add return type annotation + +auto_return_type.py:162:9: ANN201 Missing return type annotation for public function `method` + | +161 | @abc.abstractmethod +162 | def method(self): + | ^^^^^^ ANN201 +163 | """Docstring.""" + | + = help: Add return type annotation + +auto_return_type.py:166:9: ANN201 Missing return type annotation for public function `method` + | +165 | @abc.abstractmethod +166 | def method(self): + | ^^^^^^ ANN201 +167 | ... + | + = help: Add return type annotation + +auto_return_type.py:171:9: ANN205 Missing return type annotation for staticmethod `method` + | +169 | @staticmethod +170 | @abstractmethod +171 | def method(): + | ^^^^^^ ANN205 +172 | pass + | + = help: Add return type annotation + +auto_return_type.py:176:9: ANN206 Missing return type annotation for classmethod `method` + | +174 | @classmethod +175 | @abstractmethod +176 | def method(cls): + | ^^^^^^ ANN206 +177 | pass + | + = help: Add return type annotation + +auto_return_type.py:180:9: ANN201 [*] Missing return type annotation for public function `method` + | +179 | @abstractmethod +180 | def method(self): + | ^^^^^^ ANN201 +181 | if self.x > 0: +182 | return 1 + | + = help: Add return type annotation: `float` + +ℹ Unsafe fix +177 177 | pass +178 178 | +179 179 | @abstractmethod +180 |- def method(self): + 180 |+ def method(self) -> float: +181 181 | if self.x > 0: +182 182 | return 1 +183 183 | else: + + diff --git a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap index 8665fb92ce192..9be33117659ce 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap +++ b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap @@ -1,14 +1,24 @@ --- source: crates/ruff_linter/src/rules/flake8_annotations/mod.rs --- -annotation_presence.py:5:5: ANN201 Missing return type annotation for public function `foo` +annotation_presence.py:5:5: ANN201 [*] Missing return type annotation for public function `foo` | 4 | # Error 5 | def foo(a, b): | ^^^ ANN201 6 | pass | - = help: Add return type annotation + = help: Add return type annotation: `None` + +ℹ Unsafe fix +2 2 | from typing_extensions import override +3 3 | +4 4 | # Error +5 |-def foo(a, b): + 5 |+def foo(a, b) -> None: +6 6 | pass +7 7 | +8 8 | annotation_presence.py:5:9: ANN001 Missing type annotation for function argument `a` | @@ -26,14 +36,24 @@ annotation_presence.py:5:12: ANN001 Missing type annotation for function argumen 6 | pass | -annotation_presence.py:10:5: ANN201 Missing return type annotation for public function `foo` +annotation_presence.py:10:5: ANN201 [*] Missing return type annotation for public function `foo` | 9 | # Error 10 | def foo(a: int, b): | ^^^ ANN201 11 | pass | - = help: Add return type annotation + = help: Add return type annotation: `None` + +ℹ Unsafe fix +7 7 | +8 8 | +9 9 | # Error +10 |-def foo(a: int, b): + 10 |+def foo(a: int, b) -> None: +11 11 | pass +12 12 | +13 13 | annotation_presence.py:10:17: ANN001 Missing type annotation for function argument `b` | @@ -51,23 +71,43 @@ annotation_presence.py:15:17: ANN001 Missing type annotation for function argume 16 | pass | -annotation_presence.py:20:5: ANN201 Missing return type annotation for public function `foo` +annotation_presence.py:20:5: ANN201 [*] Missing return type annotation for public function `foo` | 19 | # Error 20 | def foo(a: int, b: int): | ^^^ ANN201 21 | pass | - = help: Add return type annotation + = help: Add return type annotation: `None` -annotation_presence.py:25:5: ANN201 Missing return type annotation for public function `foo` +ℹ Unsafe fix +17 17 | +18 18 | +19 19 | # Error +20 |-def foo(a: int, b: int): + 20 |+def foo(a: int, b: int) -> None: +21 21 | pass +22 22 | +23 23 | + +annotation_presence.py:25:5: ANN201 [*] Missing return type annotation for public function `foo` | 24 | # Error 25 | def foo(): | ^^^ ANN201 26 | pass | - = help: Add return type annotation + = help: Add return type annotation: `None` + +ℹ Unsafe fix +22 22 | +23 23 | +24 24 | # Error +25 |-def foo(): + 25 |+def foo() -> None: +26 26 | pass +27 27 | +28 28 | annotation_presence.py:45:12: ANN401 Dynamically typed expressions (typing.Any) are disallowed in `a` | diff --git a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__ignore_fully_untyped.snap b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__ignore_fully_untyped.snap index a93908081cec1..d806d641b4caa 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__ignore_fully_untyped.snap +++ b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__ignore_fully_untyped.snap @@ -1,13 +1,23 @@ --- source: crates/ruff_linter/src/rules/flake8_annotations/mod.rs --- -ignore_fully_untyped.py:24:5: ANN201 Missing return type annotation for public function `error_partially_typed_1` +ignore_fully_untyped.py:24:5: ANN201 [*] Missing return type annotation for public function `error_partially_typed_1` | 24 | def error_partially_typed_1(a: int, b): | ^^^^^^^^^^^^^^^^^^^^^^^ ANN201 25 | pass | - = help: Add return type annotation + = help: Add return type annotation: `None` + +ℹ Unsafe fix +21 21 | pass +22 22 | +23 23 | +24 |-def error_partially_typed_1(a: int, b): + 24 |+def error_partially_typed_1(a: int, b) -> None: +25 25 | pass +26 26 | +27 27 | ignore_fully_untyped.py:24:37: ANN001 Missing type annotation for function argument `b` | @@ -23,15 +33,25 @@ ignore_fully_untyped.py:28:37: ANN001 Missing type annotation for function argum 29 | pass | -ignore_fully_untyped.py:32:5: ANN201 Missing return type annotation for public function `error_partially_typed_3` +ignore_fully_untyped.py:32:5: ANN201 [*] Missing return type annotation for public function `error_partially_typed_3` | 32 | def error_partially_typed_3(a: int, b: int): | ^^^^^^^^^^^^^^^^^^^^^^^ ANN201 33 | pass | - = help: Add return type annotation + = help: Add return type annotation: `None` + +ℹ Unsafe fix +29 29 | pass +30 30 | +31 31 | +32 |-def error_partially_typed_3(a: int, b: int): + 32 |+def error_partially_typed_3(a: int, b: int) -> None: +33 33 | pass +34 34 | +35 35 | -ignore_fully_untyped.py:43:9: ANN201 Missing return type annotation for public function `error_typed_self` +ignore_fully_untyped.py:43:9: ANN201 [*] Missing return type annotation for public function `error_typed_self` | 41 | pass 42 | @@ -39,6 +59,14 @@ ignore_fully_untyped.py:43:9: ANN201 Missing return type annotation for public f | ^^^^^^^^^^^^^^^^ ANN201 44 | pass | - = help: Add return type annotation + = help: Add return type annotation: `None` + +ℹ Unsafe fix +40 40 | def ok_untyped_method(self): +41 41 | pass +42 42 | +43 |- def error_typed_self(self: X): + 43 |+ def error_typed_self(self: X) -> None: +44 44 | pass diff --git a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__mypy_init_return.snap b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__mypy_init_return.snap index 2ce0c94524eb4..f25fc530bc8cf 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__mypy_init_return.snap +++ b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__mypy_init_return.snap @@ -41,14 +41,24 @@ mypy_init_return.py:11:9: ANN204 [*] Missing return type annotation for special 13 13 | 14 14 | -mypy_init_return.py:40:5: ANN202 Missing return type annotation for private function `__init__` +mypy_init_return.py:40:5: ANN202 [*] Missing return type annotation for private function `__init__` | 39 | # Error 40 | def __init__(self, foo: int): | ^^^^^^^^ ANN202 41 | ... | - = help: Add return type annotation + = help: Add return type annotation: `None` + +ℹ Unsafe fix +37 37 | +38 38 | +39 39 | # Error +40 |-def __init__(self, foo: int): + 40 |+def __init__(self, foo: int) -> None: +41 41 | ... +42 42 | +43 43 | mypy_init_return.py:47:9: ANN204 [*] Missing return type annotation for special method `__init__` | diff --git a/crates/ruff_linter/src/rules/flake8_bandit/helpers.rs b/crates/ruff_linter/src/rules/flake8_bandit/helpers.rs index ad31e99137728..53ba6eddbfd4f 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/helpers.rs @@ -10,7 +10,7 @@ static PASSWORD_CANDIDATE_REGEX: Lazy = Lazy::new(|| { pub(super) fn string_literal(expr: &Expr) -> Option<&str> { match expr { - Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => Some(value), + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => Some(value.to_str()), _ => None, } } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/mod.rs b/crates/ruff_linter/src/rules/flake8_bandit/mod.rs index 3ad7a8e421b41..ce041669f1782 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/mod.rs @@ -50,6 +50,8 @@ mod tests { #[test_case(Rule::UnixCommandWildcardInjection, Path::new("S609.py"))] #[test_case(Rule::UnsafeYAMLLoad, Path::new("S506.py"))] #[test_case(Rule::WeakCryptographicKey, Path::new("S505.py"))] + #[test_case(Rule::DjangoRawSql, Path::new("S611.py"))] + #[test_case(Rule::TarfileUnsafeMembers, Path::new("S202.py"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/django_raw_sql.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/django_raw_sql.rs new file mode 100644 index 0000000000000..1491894d5b3ee --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/django_raw_sql.rs @@ -0,0 +1,58 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for uses of Django's `RawSQL` function. +/// +/// ## Why is this bad? +/// Django's `RawSQL` function can be used to execute arbitrary SQL queries, +/// which can in turn lead to SQL injection vulnerabilities. +/// +/// ## Example +/// ```python +/// from django.db.models.expressions import RawSQL +/// from django.contrib.auth.models import User +/// +/// User.objects.annotate(val=("%secure" % "nos", [])) +/// ``` +/// +/// ## References +/// - [Django documentation: SQL injection protection](https://docs.djangoproject.com/en/dev/topics/security/#sql-injection-protection) +/// - [Common Weakness Enumeration: CWE-89](https://cwe.mitre.org/data/definitions/89.html) +#[violation] +pub struct DjangoRawSql; + +impl Violation for DjangoRawSql { + #[derive_message_formats] + fn message(&self) -> String { + format!("Use of `RawSQL` can lead to SQL injection vulnerabilities") + } +} + +/// S611 +pub(crate) fn django_raw_sql(checker: &mut Checker, call: &ast::ExprCall) { + if checker + .semantic() + .resolve_call_path(&call.func) + .is_some_and(|call_path| { + matches!( + call_path.as_slice(), + ["django", "db", "models", "expressions", "RawSQL"] + ) + }) + { + if !call + .arguments + .find_argument("sql", 0) + .is_some_and(Expr::is_string_literal_expr) + { + checker + .diagnostics + .push(Diagnostic::new(DjangoRawSql, call.func.range())); + } + } +} diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_bind_all_interfaces.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_bind_all_interfaces.rs index 4fadf908a3f01..38295b71316a2 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_bind_all_interfaces.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_bind_all_interfaces.rs @@ -1,6 +1,9 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::ExprStringLiteral; +use ruff_python_ast::{self as ast, StringLike}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; /// ## What it does /// Checks for hardcoded bindings to all network interfaces (`0.0.0.0`). @@ -34,10 +37,16 @@ impl Violation for HardcodedBindAllInterfaces { } /// S104 -pub(crate) fn hardcoded_bind_all_interfaces(string: &ExprStringLiteral) -> Option { - if string.value == "0.0.0.0" { - Some(Diagnostic::new(HardcodedBindAllInterfaces, string.range)) - } else { - None +pub(crate) fn hardcoded_bind_all_interfaces(checker: &mut Checker, string: StringLike) { + let is_bind_all_interface = match string { + StringLike::StringLiteral(ast::ExprStringLiteral { value, .. }) => value == "0.0.0.0", + StringLike::FStringLiteral(ast::FStringLiteralElement { value, .. }) => value == "0.0.0.0", + StringLike::BytesLiteral(_) => return, + }; + + if is_bind_all_interface { + checker + .diagnostics + .push(Diagnostic::new(HardcodedBindAllInterfaces, string.range())); } } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_password_string.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_password_string.rs index 9839cd58ae283..07cbea8c9fbc6 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_password_string.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_password_string.rs @@ -55,7 +55,7 @@ fn password_target(target: &Expr) -> Option<&str> { Expr::Name(ast::ExprName { id, .. }) => id.as_str(), // d["password"] = "s3cr3t" Expr::Subscript(ast::ExprSubscript { slice, .. }) => match slice.as_ref() { - Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => value, + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => value.to_str(), _ => return None, }, // obj.password = "s3cr3t" diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs index d54e0a0b23afa..ff892e6b3f962 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs @@ -5,13 +5,12 @@ use ruff_python_ast::{self as ast, Expr, Operator}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::any_over_expr; -use ruff_python_semantic::SemanticModel; +use ruff_python_ast::str::raw_contents; +use ruff_source_file::Locator; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use super::super::helpers::string_literal; - static SQL_REGEX: Lazy = Lazy::new(|| { Regex::new(r"(?i)\b(select\s.+\sfrom\s|delete\s+from\s|(insert|replace)\s.+\svalues\s|update\s.+\sset\s)") .unwrap() @@ -46,53 +45,77 @@ impl Violation for HardcodedSQLExpression { } } -fn has_string_literal(expr: &Expr) -> bool { - string_literal(expr).is_some() -} - -fn matches_sql_statement(string: &str) -> bool { - SQL_REGEX.is_match(string) +/// Concatenates the contents of an f-string, without the prefix and quotes, +/// and escapes any special characters. +/// +/// ## Example +/// +/// ```python +/// "foo" f"bar {x}" "baz" +/// ``` +/// +/// becomes `foobar {x}baz`. +fn concatenated_f_string(expr: &ast::ExprFString, locator: &Locator) -> String { + expr.value + .iter() + .filter_map(|part| { + raw_contents(locator.slice(part)).map(|s| s.escape_default().to_string()) + }) + .collect() } -fn matches_string_format_expression(expr: &Expr, semantic: &SemanticModel) -> bool { - match expr { +/// S608 +pub(crate) fn hardcoded_sql_expression(checker: &mut Checker, expr: &Expr) { + let content = match expr { // "select * from table where val = " + "str" + ... - // "select * from table where val = %s" % ... Expr::BinOp(ast::ExprBinOp { - op: Operator::Add | Operator::Mod, - .. + op: Operator::Add, .. }) => { // Only evaluate the full BinOp, not the nested components. - if semantic + if !checker + .semantic() .current_expression_parent() .map_or(true, |parent| !parent.is_bin_op_expr()) { - if any_over_expr(expr, &has_string_literal) { - return true; - } + return; + } + if !any_over_expr(expr, &Expr::is_string_literal_expr) { + return; } - false + checker.generator().expr(expr) + } + // "select * from table where val = %s" % ... + Expr::BinOp(ast::ExprBinOp { + left, + op: Operator::Mod, + .. + }) => { + let Some(string) = left.as_string_literal_expr() else { + return; + }; + string.value.to_str().escape_default().to_string() } Expr::Call(ast::ExprCall { func, .. }) => { let Expr::Attribute(ast::ExprAttribute { attr, value, .. }) = func.as_ref() else { - return false; + return; }; // "select * from table where val = {}".format(...) - attr == "format" && string_literal(value).is_some() + if attr != "format" { + return; + } + let Some(string) = value.as_string_literal_expr() else { + return; + }; + string.value.to_str().escape_default().to_string() } // f"select * from table where val = {val}" - Expr::FString(_) => true, - _ => false, - } -} + Expr::FString(f_string) => concatenated_f_string(f_string, checker.locator()), + _ => return, + }; -/// S608 -pub(crate) fn hardcoded_sql_expression(checker: &mut Checker, expr: &Expr) { - if matches_string_format_expression(expr, checker.semantic()) { - if matches_sql_statement(&checker.generator().expr(expr)) { - checker - .diagnostics - .push(Diagnostic::new(HardcodedSQLExpression, expr.range())); - } + if SQL_REGEX.is_match(&content) { + checker + .diagnostics + .push(Diagnostic::new(HardcodedSQLExpression, expr.range())); } } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_tmp_directory.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_tmp_directory.rs index 1f5613647f54b..e0a66fec19631 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_tmp_directory.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/hardcoded_tmp_directory.rs @@ -1,4 +1,5 @@ -use ruff_python_ast::{self as ast, Expr}; +use ruff_python_ast::{self as ast, Expr, StringLike}; +use ruff_text_size::Ranged; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -51,13 +52,19 @@ impl Violation for HardcodedTempFile { } /// S108 -pub(crate) fn hardcoded_tmp_directory(checker: &mut Checker, string: &ast::ExprStringLiteral) { +pub(crate) fn hardcoded_tmp_directory(checker: &mut Checker, string: StringLike) { + let value = match string { + StringLike::StringLiteral(ast::ExprStringLiteral { value, .. }) => value.to_str(), + StringLike::FStringLiteral(ast::FStringLiteralElement { value, .. }) => value, + StringLike::BytesLiteral(_) => return, + }; + if !checker .settings .flake8_bandit .hardcoded_tmp_directory .iter() - .any(|prefix| string.value.starts_with(prefix)) + .any(|prefix| value.starts_with(prefix)) { return; } @@ -76,8 +83,8 @@ pub(crate) fn hardcoded_tmp_directory(checker: &mut Checker, string: &ast::ExprS checker.diagnostics.push(Diagnostic::new( HardcodedTempFile { - string: string.value.clone(), + string: value.to_string(), }, - string.range, + string.range(), )); } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs index b1ebad53e41ca..ee1de347d6152 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs @@ -1,5 +1,6 @@ pub(crate) use assert_used::*; pub(crate) use bad_file_permissions::*; +pub(crate) use django_raw_sql::*; pub(crate) use exec_used::*; pub(crate) use flask_debug_true::*; pub(crate) use hardcoded_bind_all_interfaces::*; @@ -20,6 +21,7 @@ pub(crate) use snmp_insecure_version::*; pub(crate) use snmp_weak_cryptography::*; pub(crate) use ssh_no_host_key_verification::*; pub(crate) use suspicious_function_call::*; +pub(crate) use tarfile_unsafe_members::*; pub(crate) use try_except_continue::*; pub(crate) use try_except_pass::*; pub(crate) use unsafe_yaml_load::*; @@ -27,6 +29,7 @@ pub(crate) use weak_cryptographic_key::*; mod assert_used; mod bad_file_permissions; +mod django_raw_sql; mod exec_used; mod flask_debug_true; mod hardcoded_bind_all_interfaces; @@ -47,6 +50,7 @@ mod snmp_insecure_version; mod snmp_weak_cryptography; mod ssh_no_host_key_verification; mod suspicious_function_call; +mod tarfile_unsafe_members; mod try_except_continue; mod try_except_pass; mod unsafe_yaml_load; diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_function_call.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_function_call.rs index e705676121cdd..2589b9514f2dd 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_function_call.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_function_call.rs @@ -854,11 +854,11 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, call: &ExprCall) { ["six", "moves", "urllib", "request", "urlopen" | "urlretrieve" | "Request"] => { // If the `url` argument is a string literal, allow `http` and `https` schemes. if call.arguments.args.iter().all(|arg| !arg.is_starred_expr()) && call.arguments.keywords.iter().all(|keyword| keyword.arg.is_some()) { - if let Some(Expr::StringLiteral(ast::ExprStringLiteral { value: url, .. })) = &call.arguments.find_argument("url", 0) { - let url = url.trim_start(); - if url.starts_with("http://") || url.starts_with("https://") { - return None; - } + if let Some(Expr::StringLiteral(ast::ExprStringLiteral { value, .. })) = &call.arguments.find_argument("url", 0) { + let url = value.to_str().trim_start(); + if url.starts_with("http://") || url.starts_with("https://") { + return None; + } } } Some(SuspiciousURLOpenUsage.into()) diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/tarfile_unsafe_members.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/tarfile_unsafe_members.rs new file mode 100644 index 0000000000000..b70083c8533c4 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/tarfile_unsafe_members.rs @@ -0,0 +1,75 @@ +use crate::checkers::ast::Checker; +use ruff_diagnostics::Diagnostic; +use ruff_diagnostics::Violation; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast}; +use ruff_text_size::Ranged; + +/// ## What it does +/// Checks for uses of `tarfile.extractall`. +/// +/// ## Why is this bad? +/// +/// Extracting archives from untrusted sources without prior inspection is +/// a security risk, as maliciously crafted archives may contain files that +/// will be written outside of the target directory. For example, the archive +/// could include files with absolute paths (e.g., `/etc/passwd`), or relative +/// paths with parent directory references (e.g., `../etc/passwd`). +/// +/// On Python 3.12 and later, use `filter='data'` to prevent the most dangerous +/// security issues (see: [PEP 706]). On earlier versions, set the `members` +/// argument to a trusted subset of the archive's members. +/// +/// ## Example +/// ```python +/// import tarfile +/// import tempfile +/// +/// tar = tarfile.open(filename) +/// tar.extractall(path=tempfile.mkdtemp()) +/// tar.close() +/// ``` +/// +/// ## References +/// - [Common Weakness Enumeration: CWE-22](https://cwe.mitre.org/data/definitions/22.html) +/// - [Python Documentation: `TarFile.extractall`](https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.extractall) +/// - [Python Documentation: Extraction filters](https://docs.python.org/3/library/tarfile.html#tarfile-extraction-filter) +/// +/// [PEP 706]: https://peps.python.org/pep-0706/#backporting-forward-compatibility +#[violation] +pub struct TarfileUnsafeMembers; + +impl Violation for TarfileUnsafeMembers { + #[derive_message_formats] + fn message(&self) -> String { + format!("Uses of `tarfile.extractall()`") + } +} + +/// S202 +pub(crate) fn tarfile_unsafe_members(checker: &mut Checker, call: &ast::ExprCall) { + if !call + .func + .as_attribute_expr() + .is_some_and(|attr| attr.attr.as_str() == "extractall") + { + return; + } + + if call + .arguments + .find_keyword("filter") + .and_then(|keyword| keyword.value.as_string_literal_expr()) + .is_some_and(|value| matches!(value.value.to_str(), "data" | "tar")) + { + return; + } + + if !checker.semantic().seen(&["tarfile"]) { + return; + } + + checker + .diagnostics + .push(Diagnostic::new(TarfileUnsafeMembers, call.func.range())); +} diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S104_S104.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S104_S104.py.snap index 192731979437a..b3b9ad07d38d4 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S104_S104.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S104_S104.py.snap @@ -7,6 +7,7 @@ S104.py:9:1: S104 Possible binding to all interfaces 9 | "0.0.0.0" | ^^^^^^^^^ S104 10 | '0.0.0.0' +11 | f"0.0.0.0" | S104.py:10:1: S104 Possible binding to all interfaces @@ -15,21 +16,30 @@ S104.py:10:1: S104 Possible binding to all interfaces 9 | "0.0.0.0" 10 | '0.0.0.0' | ^^^^^^^^^ S104 +11 | f"0.0.0.0" | -S104.py:14:6: S104 Possible binding to all interfaces +S104.py:11:3: S104 Possible binding to all interfaces | -13 | # Error -14 | func("0.0.0.0") + 9 | "0.0.0.0" +10 | '0.0.0.0' +11 | f"0.0.0.0" + | ^^^^^^^ S104 + | + +S104.py:15:6: S104 Possible binding to all interfaces + | +14 | # Error +15 | func("0.0.0.0") | ^^^^^^^^^ S104 | -S104.py:18:9: S104 Possible binding to all interfaces +S104.py:19:9: S104 Possible binding to all interfaces | -17 | def my_func(): -18 | x = "0.0.0.0" +18 | def my_func(): +19 | x = "0.0.0.0" | ^^^^^^^^^ S104 -19 | print(x) +20 | print(x) | diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S108_S108.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S108_S108.py.snap index 9ecf1141d98a2..7336a5015aa28 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S108_S108.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S108_S108.py.snap @@ -10,22 +10,31 @@ S108.py:5:11: S108 Probable insecure usage of temporary file or directory: "/tmp 6 | f.write("def") | -S108.py:8:11: S108 Probable insecure usage of temporary file or directory: "/var/tmp/123" +S108.py:8:13: S108 Probable insecure usage of temporary file or directory: "/tmp/abc" | 6 | f.write("def") 7 | -8 | with open("/var/tmp/123", "w") as f: - | ^^^^^^^^^^^^^^ S108 +8 | with open(f"/tmp/abc", "w") as f: + | ^^^^^^^^ S108 9 | f.write("def") | -S108.py:11:11: S108 Probable insecure usage of temporary file or directory: "/dev/shm/unit/test" +S108.py:11:11: S108 Probable insecure usage of temporary file or directory: "/var/tmp/123" | 9 | f.write("def") 10 | -11 | with open("/dev/shm/unit/test", "w") as f: - | ^^^^^^^^^^^^^^^^^^^^ S108 +11 | with open("/var/tmp/123", "w") as f: + | ^^^^^^^^^^^^^^ S108 +12 | f.write("def") + | + +S108.py:14:11: S108 Probable insecure usage of temporary file or directory: "/dev/shm/unit/test" + | 12 | f.write("def") +13 | +14 | with open("/dev/shm/unit/test", "w") as f: + | ^^^^^^^^^^^^^^^^^^^^ S108 +15 | f.write("def") | diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S108_extend.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S108_extend.snap index 998bc900593bf..b562794a05d7c 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S108_extend.snap +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S108_extend.snap @@ -10,30 +10,39 @@ S108.py:5:11: S108 Probable insecure usage of temporary file or directory: "/tmp 6 | f.write("def") | -S108.py:8:11: S108 Probable insecure usage of temporary file or directory: "/var/tmp/123" +S108.py:8:13: S108 Probable insecure usage of temporary file or directory: "/tmp/abc" | 6 | f.write("def") 7 | -8 | with open("/var/tmp/123", "w") as f: - | ^^^^^^^^^^^^^^ S108 +8 | with open(f"/tmp/abc", "w") as f: + | ^^^^^^^^ S108 9 | f.write("def") | -S108.py:11:11: S108 Probable insecure usage of temporary file or directory: "/dev/shm/unit/test" +S108.py:11:11: S108 Probable insecure usage of temporary file or directory: "/var/tmp/123" | 9 | f.write("def") 10 | -11 | with open("/dev/shm/unit/test", "w") as f: - | ^^^^^^^^^^^^^^^^^^^^ S108 +11 | with open("/var/tmp/123", "w") as f: + | ^^^^^^^^^^^^^^ S108 +12 | f.write("def") + | + +S108.py:14:11: S108 Probable insecure usage of temporary file or directory: "/dev/shm/unit/test" + | 12 | f.write("def") +13 | +14 | with open("/dev/shm/unit/test", "w") as f: + | ^^^^^^^^^^^^^^^^^^^^ S108 +15 | f.write("def") | -S108.py:15:11: S108 Probable insecure usage of temporary file or directory: "/foo/bar" +S108.py:18:11: S108 Probable insecure usage of temporary file or directory: "/foo/bar" | -14 | # not ok by config -15 | with open("/foo/bar", "w") as f: +17 | # not ok by config +18 | with open("/foo/bar", "w") as f: | ^^^^^^^^^^ S108 -16 | f.write("def") +19 | f.write("def") | diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S202_S202.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S202_S202.py.snap new file mode 100644 index 0000000000000..fb951d05d1d44 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S202_S202.py.snap @@ -0,0 +1,49 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S202.py:8:5: S202 Uses of `tarfile.extractall()` + | +6 | def unsafe_archive_handler(filename): +7 | tar = tarfile.open(filename) +8 | tar.extractall(path=tempfile.mkdtemp()) + | ^^^^^^^^^^^^^^ S202 +9 | tar.close() + | + +S202.py:14:5: S202 Uses of `tarfile.extractall()` + | +12 | def managed_members_archive_handler(filename): +13 | tar = tarfile.open(filename) +14 | tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + | ^^^^^^^^^^^^^^ S202 +15 | tar.close() + | + +S202.py:20:5: S202 Uses of `tarfile.extractall()` + | +18 | def list_members_archive_handler(filename): +19 | tar = tarfile.open(filename) +20 | tar.extractall(path=tempfile.mkdtemp(), members=[]) + | ^^^^^^^^^^^^^^ S202 +21 | tar.close() + | + +S202.py:26:5: S202 Uses of `tarfile.extractall()` + | +24 | def provided_members_archive_handler(filename): +25 | tar = tarfile.open(filename) +26 | tarfile.extractall(path=tempfile.mkdtemp(), members=tar) + | ^^^^^^^^^^^^^^^^^^ S202 +27 | tar.close() + | + +S202.py:38:5: S202 Uses of `tarfile.extractall()` + | +36 | def filter_fully_trusted(filename): +37 | tar = tarfile.open(filename) +38 | tarfile.extractall(path=tempfile.mkdtemp(), filter="fully_trusted") + | ^^^^^^^^^^^^^^^^^^ S202 +39 | tar.close() + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S611_S611.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S611_S611.py.snap new file mode 100644 index 0000000000000..026360e756ff1 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S611_S611.py.snap @@ -0,0 +1,60 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S611.py:5:27: S611 Use of `RawSQL` can lead to SQL injection vulnerabilities + | +4 | User.objects.annotate(val=RawSQL('secure', [])) +5 | User.objects.annotate(val=RawSQL('%secure' % 'nos', [])) + | ^^^^^^ S611 +6 | User.objects.annotate(val=RawSQL('{}secure'.format('no'), [])) +7 | raw = '"username") AS "val" FROM "auth_user" WHERE "username"="admin" --' + | + +S611.py:6:27: S611 Use of `RawSQL` can lead to SQL injection vulnerabilities + | +4 | User.objects.annotate(val=RawSQL('secure', [])) +5 | User.objects.annotate(val=RawSQL('%secure' % 'nos', [])) +6 | User.objects.annotate(val=RawSQL('{}secure'.format('no'), [])) + | ^^^^^^ S611 +7 | raw = '"username") AS "val" FROM "auth_user" WHERE "username"="admin" --' +8 | User.objects.annotate(val=RawSQL(raw, [])) + | + +S611.py:8:27: S611 Use of `RawSQL` can lead to SQL injection vulnerabilities + | + 6 | User.objects.annotate(val=RawSQL('{}secure'.format('no'), [])) + 7 | raw = '"username") AS "val" FROM "auth_user" WHERE "username"="admin" --' + 8 | User.objects.annotate(val=RawSQL(raw, [])) + | ^^^^^^ S611 + 9 | raw = '"username") AS "val" FROM "auth_user"' \ +10 | ' WHERE "username"="admin" OR 1=%s --' + | + +S611.py:11:27: S611 Use of `RawSQL` can lead to SQL injection vulnerabilities + | + 9 | raw = '"username") AS "val" FROM "auth_user"' \ +10 | ' WHERE "username"="admin" OR 1=%s --' +11 | User.objects.annotate(val=RawSQL(raw, [0])) + | ^^^^^^ S611 +12 | User.objects.annotate(val=RawSQL(sql='{}secure'.format('no'), params=[])) +13 | User.objects.annotate(val=RawSQL(params=[], sql='{}secure'.format('no'))) + | + +S611.py:12:27: S611 Use of `RawSQL` can lead to SQL injection vulnerabilities + | +10 | ' WHERE "username"="admin" OR 1=%s --' +11 | User.objects.annotate(val=RawSQL(raw, [0])) +12 | User.objects.annotate(val=RawSQL(sql='{}secure'.format('no'), params=[])) + | ^^^^^^ S611 +13 | User.objects.annotate(val=RawSQL(params=[], sql='{}secure'.format('no'))) + | + +S611.py:13:27: S611 Use of `RawSQL` can lead to SQL injection vulnerabilities + | +11 | User.objects.annotate(val=RawSQL(raw, [0])) +12 | User.objects.annotate(val=RawSQL(sql='{}secure'.format('no'), params=[])) +13 | User.objects.annotate(val=RawSQL(params=[], sql='{}secure'.format('no'))) + | ^^^^^^ S611 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_default_value_positional_argument.rs b/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_default_value_positional_argument.rs index 3a3618fa4d588..61134cd316b32 100644 --- a/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_default_value_positional_argument.rs +++ b/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_default_value_positional_argument.rs @@ -2,6 +2,7 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::collect_call_path; use ruff_python_ast::{Decorator, ParameterWithDefault, Parameters}; +use ruff_python_semantic::analyze::visibility; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -94,23 +95,18 @@ impl Violation for BooleanDefaultValuePositionalArgument { } } +/// FBT002 pub(crate) fn boolean_default_value_positional_argument( checker: &mut Checker, name: &str, decorator_list: &[Decorator], parameters: &Parameters, ) { + // Allow Boolean defaults in explicitly-allowed functions. if is_allowed_func_def(name) { return; } - if decorator_list.iter().any(|decorator| { - collect_call_path(&decorator.expression) - .is_some_and(|call_path| call_path.as_slice() == [name, "setter"]) - }) { - return; - } - for ParameterWithDefault { parameter, default, @@ -121,6 +117,20 @@ pub(crate) fn boolean_default_value_positional_argument( .as_ref() .is_some_and(|default| default.is_boolean_literal_expr()) { + // Allow Boolean defaults in setters. + if decorator_list.iter().any(|decorator| { + collect_call_path(&decorator.expression) + .is_some_and(|call_path| call_path.as_slice() == [name, "setter"]) + }) { + return; + } + + // Allow Boolean defaults in `@override` methods, since they're required to adhere to + // the parent signature. + if visibility::is_override(decorator_list, checker.semantic()) { + return; + } + checker.diagnostics.push(Diagnostic::new( BooleanDefaultValuePositionalArgument, parameter.name.range(), diff --git a/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs b/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs index 1ba9a680d20fe..8cfefd02f8eac 100644 --- a/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs +++ b/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs @@ -4,6 +4,7 @@ use ruff_diagnostics::Diagnostic; use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::collect_call_path; +use ruff_python_semantic::analyze::visibility; use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; @@ -109,17 +110,11 @@ pub(crate) fn boolean_type_hint_positional_argument( decorator_list: &[Decorator], parameters: &Parameters, ) { + // Allow Boolean type hints in explicitly-allowed functions. if is_allowed_func_def(name) { return; } - if decorator_list.iter().any(|decorator| { - collect_call_path(&decorator.expression) - .is_some_and(|call_path| call_path.as_slice() == [name, "setter"]) - }) { - return; - } - for ParameterWithDefault { parameter, default: _, @@ -138,9 +133,26 @@ pub(crate) fn boolean_type_hint_positional_argument( continue; } } + + // Allow Boolean type hints in setters. + if decorator_list.iter().any(|decorator| { + collect_call_path(&decorator.expression) + .is_some_and(|call_path| call_path.as_slice() == [name, "setter"]) + }) { + return; + } + + // Allow Boolean defaults in `@override` methods, since they're required to adhere to + // the parent signature. + if visibility::is_override(decorator_list, checker.semantic()) { + return; + } + + // If `bool` isn't actually a reference to the `bool` built-in, return. if !checker.semantic().is_builtin("bool") { return; } + checker.diagnostics.push(Diagnostic::new( BooleanTypeHintPositionalArgument, parameter.name.range(), diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/helpers.rs b/crates/ruff_linter/src/rules/flake8_bugbear/helpers.rs new file mode 100644 index 0000000000000..2745153c86b34 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bugbear/helpers.rs @@ -0,0 +1,28 @@ +use ruff_notebook::CellOffsets; +use ruff_python_semantic::SemanticModel; +use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; +use ruff_source_file::Locator; +use ruff_text_size::{Ranged, TextRange}; + +/// Return `true` if the statement containing the current expression is the last +/// top-level expression in the cell. This assumes that the source is a Jupyter +/// Notebook. +pub(super) fn at_last_top_level_expression_in_cell( + semantic: &SemanticModel, + locator: &Locator, + cell_offsets: Option<&CellOffsets>, +) -> bool { + if !semantic.at_top_level() { + return false; + } + let current_statement_end = semantic.current_statement().end(); + cell_offsets + .and_then(|cell_offsets| cell_offsets.containing_range(current_statement_end)) + .is_some_and(|cell_range| { + SimpleTokenizer::new( + locator.contents(), + TextRange::new(current_statement_end, cell_range.end()), + ) + .all(|token| token.kind() == SimpleTokenKind::Semi || token.kind().is_trivia()) + }) +} diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/mod.rs b/crates/ruff_linter/src/rules/flake8_bugbear/mod.rs index e31681ca43a5b..43f9aef102c9c 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/mod.rs @@ -1,4 +1,5 @@ //! Rules from [flake8-bugbear](https://pypi.org/project/flake8-bugbear/). +pub(crate) mod helpers; pub(crate) mod rules; pub mod settings; @@ -54,8 +55,10 @@ mod tests { #[test_case(Rule::UnreliableCallableCheck, Path::new("B004.py"))] #[test_case(Rule::UnusedLoopControlVariable, Path::new("B007.py"))] #[test_case(Rule::UselessComparison, Path::new("B015.py"))] + #[test_case(Rule::UselessComparison, Path::new("B015.ipynb"))] #[test_case(Rule::UselessContextlibSuppress, Path::new("B022.py"))] #[test_case(Rule::UselessExpression, Path::new("B018.py"))] + #[test_case(Rule::UselessExpression, Path::new("B018.ipynb"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs index 4c6133d779733..9ef089807f6e2 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs @@ -69,10 +69,10 @@ pub(crate) fn getattr_with_constant( let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = arg else { return; }; - if !is_identifier(value) { + if !is_identifier(value.to_str()) { return; } - if is_mangled_private(value) { + if is_mangled_private(value.to_str()) { return; } if !checker.semantic().is_builtin("getattr") { diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs index 92599a5807eba..e31d0cdc1a781 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs @@ -83,10 +83,10 @@ pub(crate) fn setattr_with_constant( let Expr::StringLiteral(ast::ExprStringLiteral { value: name, .. }) = name else { return; }; - if !is_identifier(name) { + if !is_identifier(name.to_str()) { return; } - if is_mangled_private(name) { + if is_mangled_private(name.to_str()) { return; } if !checker.semantic().is_builtin("setattr") { @@ -104,7 +104,7 @@ pub(crate) fn setattr_with_constant( if expr == child.as_ref() { let mut diagnostic = Diagnostic::new(SetAttrWithConstant, expr.range()); diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( - assignment(obj, name, value, checker.generator()), + assignment(obj, name.to_str(), value, checker.generator()), expr.range(), ))); checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs index d5f62107d46e0..373ef37732b6e 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs @@ -5,6 +5,8 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; +use super::super::helpers::at_last_top_level_expression_in_cell; + /// ## What it does /// Checks for useless comparisons. /// @@ -41,6 +43,19 @@ impl Violation for UselessComparison { /// B015 pub(crate) fn useless_comparison(checker: &mut Checker, expr: &Expr) { if expr.is_compare_expr() { + // For Jupyter Notebooks, ignore the last top-level expression for each cell. + // This is because it's common to have a cell that ends with an expression + // to display it's value. + if checker.source_type.is_ipynb() + && at_last_top_level_expression_in_cell( + checker.semantic(), + checker.locator(), + checker.cell_offsets(), + ) + { + return; + } + checker .diagnostics .push(Diagnostic::new(UselessComparison, expr.range())); diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs index 65da45af782c9..5c4f22c46c7f3 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs @@ -6,6 +6,8 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; +use super::super::helpers::at_last_top_level_expression_in_cell; + /// ## What it does /// Checks for useless expressions. /// @@ -59,6 +61,19 @@ pub(crate) fn useless_expression(checker: &mut Checker, value: &Expr) { return; } + // For Jupyter Notebooks, ignore the last top-level expression for each cell. + // This is because it's common to have a cell that ends with an expression + // to display it's value. + if checker.source_type.is_ipynb() + && at_last_top_level_expression_in_cell( + checker.semantic(), + checker.locator(), + checker.cell_offsets(), + ) + { + return; + } + // Ignore statements that have side effects. if contains_effect(value, |id| checker.semantic().is_builtin(id)) { // Flag attributes as useless expressions, even if they're attached to calls or other diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B015_B015.ipynb.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B015_B015.ipynb.snap new file mode 100644 index 0000000000000..acdae1edf4f29 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B015_B015.ipynb.snap @@ -0,0 +1,34 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +--- +B015.ipynb:5:1: B015 Pointless comparison. Did you mean to assign a value? Otherwise, prepend `assert` or remove it. + | +3 | x == 1 +4 | # Only skip the last expression +5 | x == 1 # B018 + | ^^^^^^ B015 +6 | x == 1 +7 | # Nested expressions isn't relevant + | + +B015.ipynb:9:5: B015 Pointless comparison. Did you mean to assign a value? Otherwise, prepend `assert` or remove it. + | + 7 | # Nested expressions isn't relevant + 8 | if True: + 9 | x == 1 + | ^^^^^^ B015 +10 | # Semicolons shouldn't affect the output +11 | x == 1; + | + +B015.ipynb:13:1: B015 Pointless comparison. Did you mean to assign a value? Otherwise, prepend `assert` or remove it. + | +11 | x == 1; +12 | # Semicolons with multiple expressions +13 | x == 1; x == 1 + | ^^^^^^ B015 +14 | # Comments, newlines and whitespace +15 | x == 1 # comment + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B018_B018.ipynb.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B018_B018.ipynb.snap new file mode 100644 index 0000000000000..41211ffcaef49 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B018_B018.ipynb.snap @@ -0,0 +1,34 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +--- +B018.ipynb:5:1: B018 Found useless expression. Either assign it to a variable or remove it. + | +3 | x +4 | # Only skip the last expression +5 | x # B018 + | ^ B018 +6 | x +7 | # Nested expressions isn't relevant + | + +B018.ipynb:9:5: B018 Found useless expression. Either assign it to a variable or remove it. + | + 7 | # Nested expressions isn't relevant + 8 | if True: + 9 | x + | ^ B018 +10 | # Semicolons shouldn't affect the output +11 | x; + | + +B018.ipynb:13:1: B018 Found useless expression. Either assign it to a variable or remove it. + | +11 | x; +12 | # Semicolons with multiple expressions +13 | x; x + | ^ B018 +14 | # Comments, newlines and whitespace +15 | x # comment + | + + diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs index 7772b430dc1ad..6c08ddf4a39eb 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs @@ -1083,7 +1083,7 @@ pub(crate) fn fix_unnecessary_map( // If the expression is embedded in an f-string, surround it with spaces to avoid // syntax errors. if matches!(object_type, ObjectType::Set | ObjectType::Dict) { - if parent.is_some_and(Expr::is_formatted_value_expr) { + if parent.is_some_and(Expr::is_f_string_expr) { content = format!(" {content} "); } } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs index a9191e1495e34..36d4bc1148673 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs @@ -30,6 +30,14 @@ use crate::rules::flake8_comprehensions::fixes; /// ```python /// sorted(iterable, reverse=True) /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as `reversed` and `reverse=True` will +/// yield different results in the event of custom sort keys or equality +/// functions. Specifically, `reversed` will reverse the order of the +/// collection, while `sorted` with `reverse=True` will perform a stable +/// reverse sort, which will preserve the order of elements that compare as +/// equal. #[violation] pub struct UnnecessaryCallAroundSorted { func: String, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs index 8d40f83506666..6e3eb4f4a3a62 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs @@ -32,6 +32,10 @@ use crate::rules::flake8_comprehensions::settings::Settings; /// [] /// () /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryCollectionCall { obj_type: String, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs index f11aa25b63a4e..8cf084a067b6f 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs @@ -29,6 +29,11 @@ use crate::rules::flake8_comprehensions::fixes; /// list(iterable) /// set(iterable) /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the comprehension. In most cases, though, comments will be +/// preserved. #[violation] pub struct UnnecessaryComprehension { obj_type: String, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs index 9527082ae8ebf..07fbdd9a07e91 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs @@ -40,6 +40,11 @@ use crate::rules::flake8_comprehensions::fixes; /// any(x.id for x in bar) /// all(x.id for x in bar) /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the comprehension. In most cases, though, comments will be +/// preserved. #[violation] pub struct UnnecessaryComprehensionAnyAll; diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs index 5bdeca9a5725b..10ee56f908e9a 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs @@ -43,6 +43,10 @@ use crate::rules::flake8_comprehensions::fixes; /// - Instead of `sorted(tuple(iterable))`, use `sorted(iterable)`. /// - Instead of `sorted(sorted(iterable))`, use `sorted(iterable)`. /// - Instead of `sorted(reversed(iterable))`, use `sorted(iterable)`. +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryDoubleCastOrProcess { inner: String, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs index e9be9ad143996..30a52354f380d 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs @@ -27,6 +27,10 @@ use super::helpers; /// ```python /// {x: f(x) for x in foo} /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryGeneratorDict; diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs index 06648ef7b52b7..526fe4970a1e7 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs @@ -28,6 +28,10 @@ use super::helpers; /// ```python /// [f(x) for x in foo] /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryGeneratorList; diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs index 124a838dd23a7..f2cdbf86453a0 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs @@ -28,6 +28,10 @@ use super::helpers; /// ```python /// {f(x) for x in foo} /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryGeneratorSet; diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs index 587b2754c7708..c01bf23ad3f68 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs @@ -25,6 +25,10 @@ use super::helpers; /// ```python /// [f(x) for x in foo] /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryListCall; diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs index 90b90afcddec8..1b72704fda096 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs @@ -25,6 +25,10 @@ use super::helpers; /// ```python /// {x: f(x) for x in foo} /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryListComprehensionDict; diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs index 3e5902ccd5afd..3c791385696a1 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs @@ -26,6 +26,10 @@ use super::helpers; /// ```python /// {f(x) for x in foo} /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryListComprehensionSet; diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs index 26ea9ea0d3563..1aa39d86ec178 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs @@ -29,6 +29,10 @@ use super::helpers; /// {1: 2, 3: 4} /// {} /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryLiteralDict { obj_type: String, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs index fc4c33a0e8df1..4e3d03aaf5c69 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs @@ -31,6 +31,10 @@ use super::helpers; /// {1, 2} /// set() /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryLiteralSet { obj_type: String, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs index 121ceaf685886..b407e9c0efca4 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs @@ -46,6 +46,10 @@ impl fmt::Display for DictKind { /// {} /// {"a": 1} /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryLiteralWithinDictCall { kind: DictKind, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs index 6cb4596f9f116..cbf02452d2885 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs @@ -32,6 +32,10 @@ use super::helpers; /// [1, 2] /// [1, 2] /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryLiteralWithinListCall { literal: String, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs index d1600979faf59..c3ca088c27c8e 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs @@ -33,6 +33,10 @@ use super::helpers; /// (1, 2) /// (1, 2) /// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryLiteralWithinTupleCall { literal: String, diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_map.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_map.rs index 549906f0e780c..55dc48000b471 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_map.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_map.rs @@ -22,6 +22,16 @@ use super::helpers; /// using a generator expression or a comprehension, as the latter approach /// avoids the function call overhead, in addition to being more readable. /// +/// This rule also applies to `map` calls within `list`, `set`, and `dict` +/// calls. For example: +/// +/// - Instead of `list(map(lambda num: num * 2, nums))`, use +/// `[num * 2 for num in nums]`. +/// - Instead of `set(map(lambda num: num % 2 == 0, nums))`, use +/// `{num % 2 == 0 for num in nums}`. +/// - Instead of `dict(map(lambda v: (v, v ** 2), values))`, use +/// `{v: v ** 2 for v in values}`. +/// /// ## Examples /// ```python /// map(lambda x: x + 1, iterable) @@ -32,15 +42,9 @@ use super::helpers; /// (x + 1 for x in iterable) /// ``` /// -/// This rule also applies to `map` calls within `list`, `set`, and `dict` -/// calls. For example: -/// -/// - Instead of `list(map(lambda num: num * 2, nums))`, use -/// `[num * 2 for num in nums]`. -/// - Instead of `set(map(lambda num: num % 2 == 0, nums))`, use -/// `{num % 2 == 0 for num in nums}`. -/// - Instead of `dict(map(lambda v: (v, v ** 2), values))`, use -/// `{v: v ** 2 for v in values}`. +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may occasionally drop comments +/// when rewriting the call. In most cases, though, comments will be preserved. #[violation] pub struct UnnecessaryMap { object_type: ObjectType, diff --git a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_strptime_without_zone.rs b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_strptime_without_zone.rs index 6efde68d0d2cc..8390fc9a7c969 100644 --- a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_strptime_without_zone.rs +++ b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_strptime_without_zone.rs @@ -78,7 +78,7 @@ pub(crate) fn call_datetime_strptime_without_zone(checker: &mut Checker, call: & if let Some(Expr::StringLiteral(ast::ExprStringLiteral { value: format, .. })) = call.arguments.args.get(1).as_ref() { - if format.contains("%z") { + if format.to_str().contains("%z") { return; } }; diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/all_with_model_form.rs b/crates/ruff_linter/src/rules/flake8_django/rules/all_with_model_form.rs index 8e97c68c2ca0f..8083575e2a59c 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/all_with_model_form.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/all_with_model_form.rs @@ -1,7 +1,6 @@ -use ruff_python_ast::{self as ast, Arguments, Expr, Stmt}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -48,21 +47,12 @@ impl Violation for DjangoAllWithModelForm { } /// DJ007 -pub(crate) fn all_with_model_form( - checker: &Checker, - arguments: Option<&Arguments>, - body: &[Stmt], -) -> Option { - if !arguments.is_some_and(|arguments| { - arguments - .args - .iter() - .any(|base| is_model_form(base, checker.semantic())) - }) { - return None; +pub(crate) fn all_with_model_form(checker: &mut Checker, class_def: &ast::StmtClassDef) { + if !is_model_form(class_def, checker.semantic()) { + return; } - for element in body { + for element in &class_def.body { let Stmt::ClassDef(ast::StmtClassDef { name, body, .. }) = element else { continue; }; @@ -83,12 +73,18 @@ pub(crate) fn all_with_model_form( match value.as_ref() { Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { if value == "__all__" { - return Some(Diagnostic::new(DjangoAllWithModelForm, element.range())); + checker + .diagnostics + .push(Diagnostic::new(DjangoAllWithModelForm, element.range())); + return; } } Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => { if value == "__all__".as_bytes() { - return Some(Diagnostic::new(DjangoAllWithModelForm, element.range())); + checker + .diagnostics + .push(Diagnostic::new(DjangoAllWithModelForm, element.range())); + return; } } _ => (), @@ -96,5 +92,4 @@ pub(crate) fn all_with_model_form( } } } - None } diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/exclude_with_model_form.rs b/crates/ruff_linter/src/rules/flake8_django/rules/exclude_with_model_form.rs index 41661892bb9d6..d1211c566210a 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/exclude_with_model_form.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/exclude_with_model_form.rs @@ -1,7 +1,6 @@ -use ruff_python_ast::{self as ast, Arguments, Expr, Stmt}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -46,21 +45,12 @@ impl Violation for DjangoExcludeWithModelForm { } /// DJ006 -pub(crate) fn exclude_with_model_form( - checker: &Checker, - arguments: Option<&Arguments>, - body: &[Stmt], -) -> Option { - if !arguments.is_some_and(|arguments| { - arguments - .args - .iter() - .any(|base| is_model_form(base, checker.semantic())) - }) { - return None; +pub(crate) fn exclude_with_model_form(checker: &mut Checker, class_def: &ast::StmtClassDef) { + if !is_model_form(class_def, checker.semantic()) { + return; } - for element in body { + for element in &class_def.body { let Stmt::ClassDef(ast::StmtClassDef { name, body, .. }) = element else { continue; }; @@ -76,10 +66,12 @@ pub(crate) fn exclude_with_model_form( continue; }; if id == "exclude" { - return Some(Diagnostic::new(DjangoExcludeWithModelForm, target.range())); + checker + .diagnostics + .push(Diagnostic::new(DjangoExcludeWithModelForm, target.range())); + return; } } } } - None } diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/helpers.rs b/crates/ruff_linter/src/rules/flake8_django/rules/helpers.rs index c857bec150c11..0318de183970a 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/helpers.rs @@ -1,17 +1,17 @@ -use ruff_python_ast::Expr; +use ruff_python_ast::{self as ast, Expr}; -use ruff_python_semantic::SemanticModel; +use ruff_python_semantic::{analyze, SemanticModel}; /// Return `true` if a Python class appears to be a Django model, based on its base classes. -pub(super) fn is_model(base: &Expr, semantic: &SemanticModel) -> bool { - semantic.resolve_call_path(base).is_some_and(|call_path| { +pub(super) fn is_model(class_def: &ast::StmtClassDef, semantic: &SemanticModel) -> bool { + analyze::class::any_over_body(class_def, semantic, &|call_path| { matches!(call_path.as_slice(), ["django", "db", "models", "Model"]) }) } /// Return `true` if a Python class appears to be a Django model form, based on its base classes. -pub(super) fn is_model_form(base: &Expr, semantic: &SemanticModel) -> bool { - semantic.resolve_call_path(base).is_some_and(|call_path| { +pub(super) fn is_model_form(class_def: &ast::StmtClassDef, semantic: &SemanticModel) -> bool { + analyze::class::any_over_body(class_def, semantic, &|call_path| { matches!( call_path.as_slice(), ["django", "forms", "ModelForm"] | ["django", "forms", "models", "ModelForm"] diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/model_without_dunder_str.rs b/crates/ruff_linter/src/rules/flake8_django/rules/model_without_dunder_str.rs index 9228d04753e4e..0baaeafb347f6 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/model_without_dunder_str.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/model_without_dunder_str.rs @@ -1,10 +1,9 @@ -use ruff_python_ast::{self as ast, Arguments, Expr, Stmt}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_true; +use ruff_python_ast::identifier::Identifier; +use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_python_semantic::SemanticModel; -use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -52,57 +51,39 @@ impl Violation for DjangoModelWithoutDunderStr { } /// DJ008 -pub(crate) fn model_without_dunder_str( - checker: &mut Checker, - ast::StmtClassDef { - name, - arguments, - body, - .. - }: &ast::StmtClassDef, -) { - if !is_non_abstract_model(arguments.as_deref(), body, checker.semantic()) { +pub(crate) fn model_without_dunder_str(checker: &mut Checker, class_def: &ast::StmtClassDef) { + if !is_non_abstract_model(class_def, checker.semantic()) { return; } - if has_dunder_method(body) { + if has_dunder_method(class_def) { return; } - checker - .diagnostics - .push(Diagnostic::new(DjangoModelWithoutDunderStr, name.range())); + checker.diagnostics.push(Diagnostic::new( + DjangoModelWithoutDunderStr, + class_def.identifier(), + )); } -fn has_dunder_method(body: &[Stmt]) -> bool { - body.iter().any(|val| match val { - Stmt::FunctionDef(ast::StmtFunctionDef { name, .. }) => { - if name == "__str__" { - return true; - } - false - } +/// Returns `true` if the class has `__str__` method. +fn has_dunder_method(class_def: &ast::StmtClassDef) -> bool { + class_def.body.iter().any(|val| match val { + Stmt::FunctionDef(ast::StmtFunctionDef { name, .. }) => name == "__str__", _ => false, }) } -fn is_non_abstract_model( - arguments: Option<&Arguments>, - body: &[Stmt], - semantic: &SemanticModel, -) -> bool { - let Some(Arguments { args: bases, .. }) = arguments else { - return false; - }; - - if is_model_abstract(body) { - return false; +/// Returns `true` if the class is a non-abstract Django model. +fn is_non_abstract_model(class_def: &ast::StmtClassDef, semantic: &SemanticModel) -> bool { + if class_def.bases().is_empty() || is_model_abstract(class_def) { + false + } else { + helpers::is_model(class_def, semantic) } - - bases.iter().any(|base| helpers::is_model(base, semantic)) } /// Check if class is abstract, in terms of Django model inheritance. -fn is_model_abstract(body: &[Stmt]) -> bool { - for element in body { +fn is_model_abstract(class_def: &ast::StmtClassDef) -> bool { + for element in &class_def.body { let Stmt::ClassDef(ast::StmtClassDef { name, body, .. }) = element else { continue; }; diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/unordered_body_content_in_model.rs b/crates/ruff_linter/src/rules/flake8_django/rules/unordered_body_content_in_model.rs index 01a63d4e342f9..635527dcaf014 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/unordered_body_content_in_model.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/unordered_body_content_in_model.rs @@ -1,9 +1,8 @@ use std::fmt; -use ruff_python_ast::{self as ast, Arguments, Expr, Stmt}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; @@ -79,6 +78,50 @@ impl Violation for DjangoUnorderedBodyContentInModel { } } +/// DJ012 +pub(crate) fn unordered_body_content_in_model( + checker: &mut Checker, + class_def: &ast::StmtClassDef, +) { + if !helpers::is_model(class_def, checker.semantic()) { + return; + } + + // Track all the element types we've seen so far. + let mut element_types = Vec::new(); + let mut prev_element_type = None; + for element in &class_def.body { + let Some(element_type) = get_element_type(element, checker.semantic()) else { + continue; + }; + + // Skip consecutive elements of the same type. It's less noisy to only report + // violations at type boundaries (e.g., avoid raising a violation for _every_ + // field declaration that's out of order). + if prev_element_type == Some(element_type) { + continue; + } + + prev_element_type = Some(element_type); + + if let Some(&prev_element_type) = element_types + .iter() + .find(|&&prev_element_type| prev_element_type > element_type) + { + let diagnostic = Diagnostic::new( + DjangoUnorderedBodyContentInModel { + element_type, + prev_element_type, + }, + element.range(), + ); + checker.diagnostics.push(diagnostic); + } else { + element_types.push(element_type); + } + } +} + #[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)] enum ContentType { FieldDeclaration, @@ -140,53 +183,3 @@ fn get_element_type(element: &Stmt, semantic: &SemanticModel) -> Option None, } } - -/// DJ012 -pub(crate) fn unordered_body_content_in_model( - checker: &mut Checker, - arguments: Option<&Arguments>, - body: &[Stmt], -) { - if !arguments.is_some_and(|arguments| { - arguments - .args - .iter() - .any(|base| helpers::is_model(base, checker.semantic())) - }) { - return; - } - - // Track all the element types we've seen so far. - let mut element_types = Vec::new(); - let mut prev_element_type = None; - for element in body { - let Some(element_type) = get_element_type(element, checker.semantic()) else { - continue; - }; - - // Skip consecutive elements of the same type. It's less noisy to only report - // violations at type boundaries (e.g., avoid raising a violation for _every_ - // field declaration that's out of order). - if prev_element_type == Some(element_type) { - continue; - } - - prev_element_type = Some(element_type); - - if let Some(&prev_element_type) = element_types - .iter() - .find(|&&prev_element_type| prev_element_type > element_type) - { - let diagnostic = Diagnostic::new( - DjangoUnorderedBodyContentInModel { - element_type, - prev_element_type, - }, - element.range(), - ); - checker.diagnostics.push(diagnostic); - } else { - element_types.push(element_type); - } - } -} diff --git a/crates/ruff_linter/src/rules/flake8_django/snapshots/ruff_linter__rules__flake8_django__tests__DJ012_DJ012.py.snap b/crates/ruff_linter/src/rules/flake8_django/snapshots/ruff_linter__rules__flake8_django__tests__DJ012_DJ012.py.snap index 5f15655232937..79e5d7e39539e 100644 --- a/crates/ruff_linter/src/rules/flake8_django/snapshots/ruff_linter__rules__flake8_django__tests__DJ012_DJ012.py.snap +++ b/crates/ruff_linter/src/rules/flake8_django/snapshots/ruff_linter__rules__flake8_django__tests__DJ012_DJ012.py.snap @@ -54,4 +54,12 @@ DJ012.py:129:5: DJ012 Order of model's inner classes, methods, and fields does n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DJ012 | +DJ012.py:146:5: DJ012 Order of model's inner classes, methods, and fields does not follow the Django Style Guide: field declaration should come before `Meta` class + | +144 | return "foobar" +145 | +146 | first_name = models.CharField(max_length=32) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DJ012 + | + diff --git a/crates/ruff_linter/src/rules/flake8_errmsg/rules/string_in_exception.rs b/crates/ruff_linter/src/rules/flake8_errmsg/rules/string_in_exception.rs index 173e60078977b..a7298ea73c439 100644 --- a/crates/ruff_linter/src/rules/flake8_errmsg/rules/string_in_exception.rs +++ b/crates/ruff_linter/src/rules/flake8_errmsg/rules/string_in_exception.rs @@ -191,15 +191,13 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr if let Some(indentation) = whitespace::indentation(checker.locator(), stmt) { - if checker.semantic().is_available("msg") { - diagnostic.set_fix(generate_fix( - stmt, - first, - indentation, - checker.stylist(), - checker.locator(), - )); - } + diagnostic.set_fix(generate_fix( + stmt, + first, + indentation, + checker.stylist(), + checker.locator(), + )); } checker.diagnostics.push(diagnostic); } @@ -211,15 +209,13 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr let mut diagnostic = Diagnostic::new(FStringInException, first.range()); if let Some(indentation) = whitespace::indentation(checker.locator(), stmt) { - if checker.semantic().is_available("msg") { - diagnostic.set_fix(generate_fix( - stmt, - first, - indentation, - checker.stylist(), - checker.locator(), - )); - } + diagnostic.set_fix(generate_fix( + stmt, + first, + indentation, + checker.stylist(), + checker.locator(), + )); } checker.diagnostics.push(diagnostic); } @@ -236,15 +232,13 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr if let Some(indentation) = whitespace::indentation(checker.locator(), stmt) { - if checker.semantic().is_available("msg") { - diagnostic.set_fix(generate_fix( - stmt, - first, - indentation, - checker.stylist(), - checker.locator(), - )); - } + diagnostic.set_fix(generate_fix( + stmt, + first, + indentation, + checker.stylist(), + checker.locator(), + )); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_errmsg/snapshots/ruff_linter__rules__flake8_errmsg__tests__custom.snap b/crates/ruff_linter/src/rules/flake8_errmsg/snapshots/ruff_linter__rules__flake8_errmsg__tests__custom.snap index 92912b35e263b..d29e987d4952a 100644 --- a/crates/ruff_linter/src/rules/flake8_errmsg/snapshots/ruff_linter__rules__flake8_errmsg__tests__custom.snap +++ b/crates/ruff_linter/src/rules/flake8_errmsg/snapshots/ruff_linter__rules__flake8_errmsg__tests__custom.snap @@ -59,15 +59,26 @@ EM.py:22:24: EM103 [*] Exception must not use a `.format()` string directly, ass 24 25 | 25 26 | def f_ok(): -EM.py:32:24: EM101 Exception must not use a string literal, assign to variable first +EM.py:32:24: EM101 [*] Exception must not use a string literal, assign to variable first | -30 | def f_unfixable(): +30 | def f_msg_defined(): 31 | msg = "hello" 32 | raise RuntimeError("This is an example exception") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101 | = help: Assign to variable; remove string literal +ℹ Unsafe fix +29 29 | +30 30 | def f_msg_defined(): +31 31 | msg = "hello" +32 |- raise RuntimeError("This is an example exception") + 32 |+ msg = "This is an example exception" + 33 |+ raise RuntimeError(msg) +33 34 | +34 35 | +35 36 | def f_msg_in_nested_scope(): + EM.py:39:24: EM101 [*] Exception must not use a string literal, assign to variable first | 37 | msg = "hello" @@ -88,7 +99,7 @@ EM.py:39:24: EM101 [*] Exception must not use a string literal, assign to variab 41 42 | 42 43 | def f_msg_in_parent_scope(): -EM.py:46:28: EM101 Exception must not use a string literal, assign to variable first +EM.py:46:28: EM101 [*] Exception must not use a string literal, assign to variable first | 45 | def nested(): 46 | raise RuntimeError("This is an example exception") @@ -96,6 +107,17 @@ EM.py:46:28: EM101 Exception must not use a string literal, assign to variable f | = help: Assign to variable; remove string literal +ℹ Unsafe fix +43 43 | msg = "hello" +44 44 | +45 45 | def nested(): +46 |- raise RuntimeError("This is an example exception") + 46 |+ msg = "This is an example exception" + 47 |+ raise RuntimeError(msg) +47 48 | +48 49 | +49 50 | def f_fix_indentation_check(foo): + EM.py:51:28: EM101 [*] Exception must not use a string literal, assign to variable first | 49 | def f_fix_indentation_check(foo): diff --git a/crates/ruff_linter/src/rules/flake8_errmsg/snapshots/ruff_linter__rules__flake8_errmsg__tests__defaults.snap b/crates/ruff_linter/src/rules/flake8_errmsg/snapshots/ruff_linter__rules__flake8_errmsg__tests__defaults.snap index a50458f892404..593d6b30dcc0e 100644 --- a/crates/ruff_linter/src/rules/flake8_errmsg/snapshots/ruff_linter__rules__flake8_errmsg__tests__defaults.snap +++ b/crates/ruff_linter/src/rules/flake8_errmsg/snapshots/ruff_linter__rules__flake8_errmsg__tests__defaults.snap @@ -97,15 +97,26 @@ EM.py:22:24: EM103 [*] Exception must not use a `.format()` string directly, ass 24 25 | 25 26 | def f_ok(): -EM.py:32:24: EM101 Exception must not use a string literal, assign to variable first +EM.py:32:24: EM101 [*] Exception must not use a string literal, assign to variable first | -30 | def f_unfixable(): +30 | def f_msg_defined(): 31 | msg = "hello" 32 | raise RuntimeError("This is an example exception") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101 | = help: Assign to variable; remove string literal +ℹ Unsafe fix +29 29 | +30 30 | def f_msg_defined(): +31 31 | msg = "hello" +32 |- raise RuntimeError("This is an example exception") + 32 |+ msg = "This is an example exception" + 33 |+ raise RuntimeError(msg) +33 34 | +34 35 | +35 36 | def f_msg_in_nested_scope(): + EM.py:39:24: EM101 [*] Exception must not use a string literal, assign to variable first | 37 | msg = "hello" @@ -126,7 +137,7 @@ EM.py:39:24: EM101 [*] Exception must not use a string literal, assign to variab 41 42 | 42 43 | def f_msg_in_parent_scope(): -EM.py:46:28: EM101 Exception must not use a string literal, assign to variable first +EM.py:46:28: EM101 [*] Exception must not use a string literal, assign to variable first | 45 | def nested(): 46 | raise RuntimeError("This is an example exception") @@ -134,6 +145,17 @@ EM.py:46:28: EM101 Exception must not use a string literal, assign to variable f | = help: Assign to variable; remove string literal +ℹ Unsafe fix +43 43 | msg = "hello" +44 44 | +45 45 | def nested(): +46 |- raise RuntimeError("This is an example exception") + 46 |+ msg = "This is an example exception" + 47 |+ raise RuntimeError(msg) +47 48 | +48 49 | +49 50 | def f_fix_indentation_check(foo): + EM.py:51:28: EM101 [*] Exception must not use a string literal, assign to variable first | 49 | def f_fix_indentation_check(foo): diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs b/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs index 4b214fffec95f..bd1e6399df596 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs +++ b/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs @@ -93,7 +93,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) { for key in keys { if let Some(key) = &key { if let Expr::StringLiteral(ast::ExprStringLiteral { value: attr, .. }) = key { - if is_reserved_attr(attr) { + if is_reserved_attr(attr.to_str()) { checker.diagnostics.push(Diagnostic::new( LoggingExtraAttrClash(attr.to_string()), key.range(), diff --git a/crates/ruff_linter/src/rules/flake8_pie/mod.rs b/crates/ruff_linter/src/rules/flake8_pie/mod.rs index 238c239add39e..046b43b097aae 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/mod.rs @@ -21,6 +21,7 @@ mod tests { #[test_case(Rule::UnnecessarySpread, Path::new("PIE800.py"))] #[test_case(Rule::ReimplementedContainerBuiltin, Path::new("PIE807.py"))] #[test_case(Rule::NonUniqueEnums, Path::new("PIE796.py"))] + #[test_case(Rule::NonUniqueEnums, Path::new("PIE796.pyi"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/non_unique_enums.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/non_unique_enums.rs index 6a0e62b47c307..36f54f444f88d 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/non_unique_enums.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/non_unique_enums.rs @@ -4,7 +4,7 @@ use ruff_diagnostics::Diagnostic; use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; -use ruff_python_ast::{self as ast, Expr, Stmt}; +use ruff_python_ast::{self as ast, Expr, PySourceType, Stmt}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -84,7 +84,15 @@ pub(crate) fn non_unique_enums(checker: &mut Checker, parent: &Stmt, body: &[Stm } } - if !seen_targets.insert(ComparableExpr::from(value)) { + let comparable = ComparableExpr::from(value); + + if checker.source_type == PySourceType::Stub + && comparable == ComparableExpr::EllipsisLiteral + { + continue; + } + + if !seen_targets.insert(comparable) { let diagnostic = Diagnostic::new( NonUniqueEnums { value: checker.generator().expr(value), diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs index 8a518c88906f4..5f0bf0abb48d0 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs @@ -1,13 +1,16 @@ +use std::hash::BuildHasherDefault; + use itertools::Itertools; -use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; -use ruff_python_ast::{self as ast, Expr, Keyword}; +use rustc_hash::FxHashSet; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_text_size::Ranged; - +use ruff_python_ast::{self as ast, Expr}; use ruff_python_stdlib::identifiers::is_identifier; +use ruff_text_size::Ranged; use crate::checkers::ast::Checker; +use crate::fix::edits::{remove_argument, Parentheses}; /// ## What it does /// Checks for unnecessary `dict` kwargs. @@ -40,36 +43,39 @@ use crate::checkers::ast::Checker; #[violation] pub struct UnnecessaryDictKwargs; -impl AlwaysFixableViolation for UnnecessaryDictKwargs { +impl Violation for UnnecessaryDictKwargs { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary `dict` kwargs") } - fn fix_title(&self) -> String { - format!("Remove unnecessary kwargs") + fn fix_title(&self) -> Option { + Some(format!("Remove unnecessary kwargs")) } } /// PIE804 -pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs: &[Keyword]) { - for kw in kwargs { - // keyword is a spread operator (indicated by None) - if kw.arg.is_some() { +pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, call: &ast::ExprCall) { + let mut duplicate_keywords = None; + for keyword in &call.arguments.keywords { + // keyword is a spread operator (indicated by None). + if keyword.arg.is_some() { continue; } - let Expr::Dict(ast::ExprDict { keys, values, .. }) = &kw.value else { + let Expr::Dict(ast::ExprDict { keys, values, .. }) = &keyword.value else { continue; }; // Ex) `foo(**{**bar})` if matches!(keys.as_slice(), [None]) { - let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, expr.range()); + let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, keyword.range()); diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( format!("**{}", checker.locator().slice(values[0].range())), - kw.range(), + keyword.range(), ))); checker.diagnostics.push(diagnostic); @@ -86,32 +92,82 @@ pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs continue; } - let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, expr.range()); + let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, keyword.range()); if values.is_empty() { - diagnostic.set_fix(Fix::safe_edit(Edit::deletion(kw.start(), kw.end()))); + diagnostic.try_set_fix(|| { + remove_argument( + keyword, + &call.arguments, + Parentheses::Preserve, + checker.locator().contents(), + ) + .map(Fix::safe_edit) + }); } else { - diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( - kwargs + // Compute the set of duplicate keywords (lazily). + if duplicate_keywords.is_none() { + duplicate_keywords = Some(duplicates(call)); + } + + // Avoid fixing if doing so could introduce a duplicate keyword argument. + if let Some(duplicate_keywords) = duplicate_keywords.as_ref() { + if kwargs .iter() - .zip(values.iter()) - .map(|(kwarg, value)| { - format!("{}={}", kwarg, checker.locator().slice(value.range())) - }) - .join(", "), - kw.range(), - ))); + .all(|kwarg| !duplicate_keywords.contains(kwarg)) + { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + kwargs + .iter() + .zip(values.iter()) + .map(|(kwarg, value)| { + format!("{}={}", kwarg, checker.locator().slice(value.range())) + }) + .join(", "), + keyword.range(), + ))); + } + } } checker.diagnostics.push(diagnostic); } } +/// Determine the set of keywords that appear in multiple positions (either directly, as in +/// `func(x=1)`, or indirectly, as in `func(**{"x": 1})`). +fn duplicates(call: &ast::ExprCall) -> FxHashSet<&str> { + let mut seen = FxHashSet::with_capacity_and_hasher( + call.arguments.keywords.len(), + BuildHasherDefault::default(), + ); + let mut duplicates = FxHashSet::with_capacity_and_hasher( + call.arguments.keywords.len(), + BuildHasherDefault::default(), + ); + for keyword in &call.arguments.keywords { + if let Some(name) = &keyword.arg { + if !seen.insert(name.as_str()) { + duplicates.insert(name.as_str()); + } + } else if let Expr::Dict(ast::ExprDict { keys, .. }) = &keyword.value { + for key in keys { + if let Some(name) = key.as_ref().and_then(as_kwarg) { + if !seen.insert(name) { + duplicates.insert(name); + } + } + } + } + } + duplicates +} + /// Return `Some` if a key is a valid keyword argument name, or `None` otherwise. fn as_kwarg(key: &Expr) -> Option<&str> { if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = key { - if is_identifier(value) { - return Some(value); + if is_identifier(value.to_str()) { + return Some(value.to_str()); } } None diff --git a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE796_PIE796.py.snap b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE796_PIE796.py.snap index df58500ba5ef4..e10325ed1b541 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE796_PIE796.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE796_PIE796.py.snap @@ -57,4 +57,21 @@ PIE796.py:54:5: PIE796 Enum contains duplicate value: `2` | ^^^^^ PIE796 | +PIE796.py:71:5: PIE796 Enum contains duplicate value: `...` + | +69 | class FakeEnum10(enum.Enum): +70 | A = ... +71 | B = ... # PIE796 + | ^^^^^^^ PIE796 +72 | C = ... # PIE796 + | + +PIE796.py:72:5: PIE796 Enum contains duplicate value: `...` + | +70 | A = ... +71 | B = ... # PIE796 +72 | C = ... # PIE796 + | ^^^^^^^ PIE796 + | + diff --git a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE796_PIE796.pyi.snap b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE796_PIE796.pyi.snap new file mode 100644 index 0000000000000..5c6e954faaa5a --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE796_PIE796.pyi.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/flake8_pie/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE804_PIE804.py.snap b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE804_PIE804.py.snap index 450ed048e6e4a..15d993a0befee 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE804_PIE804.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE804_PIE804.py.snap @@ -1,10 +1,10 @@ --- source: crates/ruff_linter/src/rules/flake8_pie/mod.rs --- -PIE804.py:1:1: PIE804 [*] Unnecessary `dict` kwargs +PIE804.py:1:5: PIE804 [*] Unnecessary `dict` kwargs | 1 | foo(**{"bar": True}) # PIE804 - | ^^^^^^^^^^^^^^^^^^^^ PIE804 + | ^^^^^^^^^^^^^^^ PIE804 2 | 3 | foo(**{"r2d2": True}) # PIE804 | @@ -17,12 +17,12 @@ PIE804.py:1:1: PIE804 [*] Unnecessary `dict` kwargs 3 3 | foo(**{"r2d2": True}) # PIE804 4 4 | -PIE804.py:3:1: PIE804 [*] Unnecessary `dict` kwargs +PIE804.py:3:5: PIE804 [*] Unnecessary `dict` kwargs | 1 | foo(**{"bar": True}) # PIE804 2 | 3 | foo(**{"r2d2": True}) # PIE804 - | ^^^^^^^^^^^^^^^^^^^^^ PIE804 + | ^^^^^^^^^^^^^^^^ PIE804 4 | 5 | Foo.objects.create(**{"bar": True}) # PIE804 | @@ -37,12 +37,12 @@ PIE804.py:3:1: PIE804 [*] Unnecessary `dict` kwargs 5 5 | Foo.objects.create(**{"bar": True}) # PIE804 6 6 | -PIE804.py:5:1: PIE804 [*] Unnecessary `dict` kwargs +PIE804.py:5:20: PIE804 [*] Unnecessary `dict` kwargs | 3 | foo(**{"r2d2": True}) # PIE804 4 | 5 | Foo.objects.create(**{"bar": True}) # PIE804 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PIE804 + | ^^^^^^^^^^^^^^^ PIE804 6 | 7 | Foo.objects.create(**{"_id": some_id}) # PIE804 | @@ -58,12 +58,12 @@ PIE804.py:5:1: PIE804 [*] Unnecessary `dict` kwargs 7 7 | Foo.objects.create(**{"_id": some_id}) # PIE804 8 8 | -PIE804.py:7:1: PIE804 [*] Unnecessary `dict` kwargs +PIE804.py:7:20: PIE804 [*] Unnecessary `dict` kwargs | 5 | Foo.objects.create(**{"bar": True}) # PIE804 6 | 7 | Foo.objects.create(**{"_id": some_id}) # PIE804 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PIE804 + | ^^^^^^^^^^^^^^^^^^ PIE804 8 | 9 | Foo.objects.create(**{**bar}) # PIE804 | @@ -79,12 +79,12 @@ PIE804.py:7:1: PIE804 [*] Unnecessary `dict` kwargs 9 9 | Foo.objects.create(**{**bar}) # PIE804 10 10 | -PIE804.py:9:1: PIE804 [*] Unnecessary `dict` kwargs +PIE804.py:9:20: PIE804 [*] Unnecessary `dict` kwargs | 7 | Foo.objects.create(**{"_id": some_id}) # PIE804 8 | 9 | Foo.objects.create(**{**bar}) # PIE804 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PIE804 + | ^^^^^^^^^ PIE804 10 | 11 | foo(**{}) | @@ -100,12 +100,14 @@ PIE804.py:9:1: PIE804 [*] Unnecessary `dict` kwargs 11 11 | foo(**{}) 12 12 | -PIE804.py:11:1: PIE804 [*] Unnecessary `dict` kwargs +PIE804.py:11:5: PIE804 [*] Unnecessary `dict` kwargs | 9 | Foo.objects.create(**{**bar}) # PIE804 10 | 11 | foo(**{}) - | ^^^^^^^^^ PIE804 + | ^^^^ PIE804 +12 | +13 | foo(**{**data, "foo": "buzz"}) | = help: Remove unnecessary kwargs @@ -116,7 +118,71 @@ PIE804.py:11:1: PIE804 [*] Unnecessary `dict` kwargs 11 |-foo(**{}) 11 |+foo() 12 12 | -13 13 | -14 14 | foo(**{**data, "foo": "buzz"}) +13 13 | foo(**{**data, "foo": "buzz"}) +14 14 | foo(**buzz) + +PIE804.py:22:5: PIE804 [*] Unnecessary `dict` kwargs + | +20 | foo(**{f"buzz__{bar}": True}) +21 | abc(**{"for": 3}) +22 | foo(**{},) + | ^^^^ PIE804 +23 | +24 | # Duplicated key names won't be fixed, to avoid syntax errors. + | + = help: Remove unnecessary kwargs + +ℹ Safe fix +19 19 | foo(**{"": True}) +20 20 | foo(**{f"buzz__{bar}": True}) +21 21 | abc(**{"for": 3}) +22 |-foo(**{},) + 22 |+foo() +23 23 | +24 24 | # Duplicated key names won't be fixed, to avoid syntax errors. +25 25 | abc(**{'a': b}, **{'a': c}) # PIE804 + +PIE804.py:25:5: PIE804 Unnecessary `dict` kwargs + | +24 | # Duplicated key names won't be fixed, to avoid syntax errors. +25 | abc(**{'a': b}, **{'a': c}) # PIE804 + | ^^^^^^^^^^ PIE804 +26 | abc(a=1, **{'a': c}, **{'b': c}) # PIE804 + | + = help: Remove unnecessary kwargs + +PIE804.py:25:17: PIE804 Unnecessary `dict` kwargs + | +24 | # Duplicated key names won't be fixed, to avoid syntax errors. +25 | abc(**{'a': b}, **{'a': c}) # PIE804 + | ^^^^^^^^^^ PIE804 +26 | abc(a=1, **{'a': c}, **{'b': c}) # PIE804 + | + = help: Remove unnecessary kwargs + +PIE804.py:26:10: PIE804 Unnecessary `dict` kwargs + | +24 | # Duplicated key names won't be fixed, to avoid syntax errors. +25 | abc(**{'a': b}, **{'a': c}) # PIE804 +26 | abc(a=1, **{'a': c}, **{'b': c}) # PIE804 + | ^^^^^^^^^^ PIE804 + | + = help: Remove unnecessary kwargs + +PIE804.py:26:22: PIE804 [*] Unnecessary `dict` kwargs + | +24 | # Duplicated key names won't be fixed, to avoid syntax errors. +25 | abc(**{'a': b}, **{'a': c}) # PIE804 +26 | abc(a=1, **{'a': c}, **{'b': c}) # PIE804 + | ^^^^^^^^^^ PIE804 + | + = help: Remove unnecessary kwargs + +ℹ Safe fix +23 23 | +24 24 | # Duplicated key names won't be fixed, to avoid syntax errors. +25 25 | abc(**{'a': b}, **{'a': c}) # PIE804 +26 |-abc(a=1, **{'a': c}, **{'b': c}) # PIE804 + 26 |+abc(a=1, **{'a': c}, b=c) # PIE804 diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs index f10946236be2d..01350b9501cc0 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs @@ -2,7 +2,7 @@ use std::fmt; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::Parameters; +use ruff_python_ast::{Expr, Parameters}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -51,6 +51,9 @@ impl Violation for NoReturnArgumentAnnotationInStub { /// PYI050 pub(crate) fn no_return_argument_annotation(checker: &mut Checker, parameters: &Parameters) { + // Ex) def func(arg: NoReturn): ... + // Ex) def func(arg: NoReturn, /): ... + // Ex) def func(*, arg: NoReturn): ... for annotation in parameters .posonlyargs .iter() @@ -58,21 +61,39 @@ pub(crate) fn no_return_argument_annotation(checker: &mut Checker, parameters: & .chain(¶meters.kwonlyargs) .filter_map(|arg| arg.parameter.annotation.as_ref()) { - if checker.semantic().match_typing_expr(annotation, "NoReturn") { - checker.diagnostics.push(Diagnostic::new( - NoReturnArgumentAnnotationInStub { - module: if checker.settings.target_version >= Py311 { - TypingModule::Typing - } else { - TypingModule::TypingExtensions - }, - }, - annotation.range(), - )); + check_no_return_argument_annotation(checker, annotation); + } + + // Ex) def func(*args: NoReturn): ... + if let Some(arg) = ¶meters.vararg { + if let Some(annotation) = &arg.annotation { + check_no_return_argument_annotation(checker, annotation); + } + } + + // Ex) def func(**kwargs: NoReturn): ... + if let Some(arg) = ¶meters.kwarg { + if let Some(annotation) = &arg.annotation { + check_no_return_argument_annotation(checker, annotation); } } } +fn check_no_return_argument_annotation(checker: &mut Checker, annotation: &Expr) { + if checker.semantic().match_typing_expr(annotation, "NoReturn") { + checker.diagnostics.push(Diagnostic::new( + NoReturnArgumentAnnotationInStub { + module: if checker.settings.target_version >= Py311 { + TypingModule::Typing + } else { + TypingModule::TypingExtensions + }, + }, + annotation.range(), + )); + } +} + #[derive(Debug, PartialEq, Eq)] enum TypingModule { Typing, diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs index d8fa801c942f9..df2b034e82513 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs @@ -1,8 +1,7 @@ -use ruff_python_ast::{self as ast, Expr}; - use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_docstring_stmt; +use ruff_python_ast::{self as ast, StringLike}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -44,25 +43,27 @@ impl AlwaysFixableViolation for StringOrBytesTooLong { } /// PYI053 -pub(crate) fn string_or_bytes_too_long(checker: &mut Checker, expr: &Expr) { +pub(crate) fn string_or_bytes_too_long(checker: &mut Checker, string: StringLike) { // Ignore docstrings. if is_docstring_stmt(checker.semantic().current_statement()) { return; } - let length = match expr { - Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => value.chars().count(), - Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => value.len(), - _ => return, + let length = match string { + StringLike::StringLiteral(ast::ExprStringLiteral { value, .. }) => value.chars().count(), + StringLike::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => value.len(), + StringLike::FStringLiteral(ast::FStringLiteralElement { value, .. }) => { + value.chars().count() + } }; if length <= 50 { return; } - let mut diagnostic = Diagnostic::new(StringOrBytesTooLong, expr.range()); + let mut diagnostic = Diagnostic::new(StringOrBytesTooLong, string.range()); diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( "...".to_string(), - expr.range(), + string.range(), ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/type_alias_naming.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/type_alias_naming.rs index e240bd3bd8191..4e60317211c2c 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/type_alias_naming.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/type_alias_naming.rs @@ -46,12 +46,16 @@ impl Violation for SnakeCaseTypeAlias { /// /// ## Example /// ```python -/// MyTypeT = int +/// from typing import TypeAlias +/// +/// _MyTypeT: TypeAlias = int /// ``` /// /// Use instead: /// ```python -/// MyType = int +/// from typing import TypeAlias +/// +/// _MyType: TypeAlias = int /// ``` #[violation] pub struct TSuffixedTypeAlias { diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_literal_union.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_literal_union.rs index 187837905fe60..7b56371e837c3 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_literal_union.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_literal_union.rs @@ -1,9 +1,11 @@ -use ruff_diagnostics::{Diagnostic, Violation}; +use ast::{ExprSubscript, Operator}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr}; -use ruff_text_size::Ranged; +use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; + use crate::rules::flake8_pyi::helpers::traverse_union; /// ## What it does @@ -32,6 +34,8 @@ pub struct UnnecessaryLiteralUnion { } impl Violation for UnnecessaryLiteralUnion { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + #[derive_message_formats] fn message(&self) -> String { format!( @@ -39,36 +43,153 @@ impl Violation for UnnecessaryLiteralUnion { self.members.join(", ") ) } + + fn fix_title(&self) -> Option { + Some(format!("Replace with a single `Literal`",)) + } +} + +fn concatenate_bin_ors(exprs: Vec<&Expr>) -> Expr { + let mut exprs = exprs.into_iter(); + let first = exprs.next().unwrap(); + exprs.fold((*first).clone(), |acc, expr| { + Expr::BinOp(ast::ExprBinOp { + left: Box::new(acc), + op: Operator::BitOr, + right: Box::new((*expr).clone()), + range: TextRange::default(), + }) + }) +} + +fn make_union(subscript: &ExprSubscript, exprs: Vec<&Expr>) -> Expr { + Expr::Subscript(ast::ExprSubscript { + value: subscript.value.clone(), + slice: Box::new(Expr::Tuple(ast::ExprTuple { + elts: exprs.into_iter().map(|expr| (*expr).clone()).collect(), + range: TextRange::default(), + ctx: ast::ExprContext::Load, + })), + range: TextRange::default(), + ctx: ast::ExprContext::Load, + }) +} + +fn make_literal_expr(subscript: Option, exprs: Vec<&Expr>) -> Expr { + let use_subscript = if let subscript @ Some(_) = subscript { + subscript.unwrap().clone() + } else { + Expr::Name(ast::ExprName { + id: "Literal".to_string(), + range: TextRange::default(), + ctx: ast::ExprContext::Load, + }) + }; + Expr::Subscript(ast::ExprSubscript { + value: Box::new(use_subscript), + slice: Box::new(Expr::Tuple(ast::ExprTuple { + elts: exprs.into_iter().map(|expr| (*expr).clone()).collect(), + range: TextRange::default(), + ctx: ast::ExprContext::Load, + })), + range: TextRange::default(), + ctx: ast::ExprContext::Load, + }) } /// PYI030 pub(crate) fn unnecessary_literal_union<'a>(checker: &mut Checker, expr: &'a Expr) { let mut literal_exprs = Vec::new(); + let mut other_exprs = Vec::new(); + + // for the sake of consistency and correctness, we'll use the first `Literal` subscript attribute + // to construct the fix + let mut literal_subscript = None; + let mut total_literals = 0; - // Adds a member to `literal_exprs` if it is a `Literal` annotation + // Split members into `literal_exprs` if they are a `Literal` annotation and `other_exprs` otherwise let mut collect_literal_expr = |expr: &'a Expr, _| { if let Expr::Subscript(ast::ExprSubscript { value, slice, .. }) = expr { if checker.semantic().match_typing_expr(value, "Literal") { - literal_exprs.push(slice); + total_literals += 1; + + if literal_subscript.is_none() { + literal_subscript = Some(*value.clone()); + } + + // flatten already-unioned literals to later union again + if let Expr::Tuple(ast::ExprTuple { + elts, + range: _, + ctx: _, + }) = slice.as_ref() + { + for expr in elts { + literal_exprs.push(expr); + } + } else { + literal_exprs.push(slice.as_ref()); + } } + } else { + other_exprs.push(expr); } }; - // Traverse the union, collect all literal members + // Traverse the union, collect all members, split out the literals from the rest. traverse_union(&mut collect_literal_expr, checker.semantic(), expr, None); - // Raise a violation if more than one - if literal_exprs.len() > 1 { - let diagnostic = Diagnostic::new( + let union_subscript = expr.as_subscript_expr(); + if union_subscript.is_some_and(|subscript| { + !checker + .semantic() + .match_typing_expr(&subscript.value, "Union") + }) { + return; + } + + // Raise a violation if more than one. + if total_literals > 1 { + let literal_members: Vec = literal_exprs + .clone() + .into_iter() + .map(|expr| checker.locator().slice(expr).to_string()) + .collect(); + + let mut diagnostic = Diagnostic::new( UnnecessaryLiteralUnion { - members: literal_exprs - .into_iter() - .map(|expr| checker.locator().slice(expr.as_ref()).to_string()) - .collect(), + members: literal_members.clone(), }, expr.range(), ); + if checker.settings.preview.is_enabled() { + let literals = + make_literal_expr(literal_subscript, literal_exprs.into_iter().collect()); + + if other_exprs.is_empty() { + // if the union is only literals, we just replace the whole thing with a single literal + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + checker.generator().expr(&literals), + expr.range(), + ))); + } else { + let mut expr_vec: Vec<&Expr> = other_exprs.clone().into_iter().collect(); + expr_vec.insert(0, &literals); + + let content = if let Some(subscript) = union_subscript { + checker.generator().expr(&make_union(subscript, expr_vec)) + } else { + checker.generator().expr(&concatenate_bin_ors(expr_vec)) + }; + + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + content, + expr.range(), + ))); + } + } + checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_platform.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_platform.rs index dc84fdffa10f8..17c82b398a635 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_platform.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_platform.rs @@ -127,10 +127,10 @@ pub(crate) fn unrecognized_platform(checker: &mut Checker, test: &Expr) { // Other values are possible but we don't need them right now. // This protects against typos. if checker.enabled(Rule::UnrecognizedPlatformName) { - if !matches!(value.as_str(), "linux" | "win32" | "cygwin" | "darwin") { + if !matches!(value.to_str(), "linux" | "win32" | "cygwin" | "darwin") { checker.diagnostics.push(Diagnostic::new( UnrecognizedPlatformName { - platform: value.clone(), + platform: value.to_string(), }, right.range(), )); diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI030_PYI030.py.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI030_PYI030.py.snap index 8f6838bde1deb..b06ed30fe2396 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI030_PYI030.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI030_PYI030.py.snap @@ -9,6 +9,7 @@ PYI030.py:9:9: PYI030 Multiple literal members in a union. Use a single literal, 10 | 11 | # Should emit for union types in arguments. | + = help: Replace with a single `Literal` PYI030.py:12:17: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -17,6 +18,7 @@ PYI030.py:12:17: PYI030 Multiple literal members in a union. Use a single litera | ^^^^^^^^^^^^^^^^^^^^^^^ PYI030 13 | print(arg1) | + = help: Replace with a single `Literal` PYI030.py:17:16: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -25,6 +27,7 @@ PYI030.py:17:16: PYI030 Multiple literal members in a union. Use a single litera | ^^^^^^^^^^^^^^^^^^^^^^^ PYI030 18 | return "my Literal[1]ing" | + = help: Replace with a single `Literal` PYI030.py:22:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -34,6 +37,7 @@ PYI030.py:22:9: PYI030 Multiple literal members in a union. Use a single literal 23 | field4: str | Literal[1] | Literal[2] # Error 24 | field5: Literal[1] | str | Literal[2] # Error | + = help: Replace with a single `Literal` PYI030.py:23:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -44,6 +48,7 @@ PYI030.py:23:9: PYI030 Multiple literal members in a union. Use a single literal 24 | field5: Literal[1] | str | Literal[2] # Error 25 | field6: Literal[1] | bool | Literal[2] | str # Error | + = help: Replace with a single `Literal` PYI030.py:24:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -53,6 +58,7 @@ PYI030.py:24:9: PYI030 Multiple literal members in a union. Use a single literal | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 25 | field6: Literal[1] | bool | Literal[2] | str # Error | + = help: Replace with a single `Literal` PYI030.py:25:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -63,6 +69,7 @@ PYI030.py:25:9: PYI030 Multiple literal members in a union. Use a single literal 26 | 27 | # Should emit for non-type unions. | + = help: Replace with a single `Literal` PYI030.py:28:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -72,6 +79,7 @@ PYI030.py:28:10: PYI030 Multiple literal members in a union. Use a single litera 29 | 30 | # Should emit for parenthesized unions. | + = help: Replace with a single `Literal` PYI030.py:31:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -81,6 +89,7 @@ PYI030.py:31:9: PYI030 Multiple literal members in a union. Use a single literal 32 | 33 | # Should handle user parentheses when fixing. | + = help: Replace with a single `Literal` PYI030.py:34:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -89,6 +98,7 @@ PYI030.py:34:9: PYI030 Multiple literal members in a union. Use a single literal | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 35 | field10: (Literal[1] | str) | Literal[2] # Error | + = help: Replace with a single `Literal` PYI030.py:35:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -99,12 +109,160 @@ PYI030.py:35:10: PYI030 Multiple literal members in a union. Use a single litera 36 | 37 | # Should emit for union in generic parent type. | + = help: Replace with a single `Literal` PYI030.py:38:15: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | 37 | # Should emit for union in generic parent type. 38 | field11: dict[Literal[1] | Literal[2], str] # Error | ^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +39 | +40 | # Should emit for unions with more than two cases | + = help: Replace with a single `Literal` + +PYI030.py:41:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3]` + | +40 | # Should emit for unions with more than two cases +41 | field12: Literal[1] | Literal[2] | Literal[3] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +42 | field13: Literal[1] | Literal[2] | Literal[3] | Literal[4] # Error + | + = help: Replace with a single `Literal` + +PYI030.py:42:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3, 4]` + | +40 | # Should emit for unions with more than two cases +41 | field12: Literal[1] | Literal[2] | Literal[3] # Error +42 | field13: Literal[1] | Literal[2] | Literal[3] | Literal[4] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +43 | +44 | # Should emit for unions with more than two cases, even if not directly adjacent + | + = help: Replace with a single `Literal` + +PYI030.py:45:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3]` + | +44 | # Should emit for unions with more than two cases, even if not directly adjacent +45 | field14: Literal[1] | Literal[2] | str | Literal[3] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +46 | +47 | # Should emit for unions with mixed literal internal types + | + = help: Replace with a single `Literal` + +PYI030.py:48:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, "foo", True]` + | +47 | # Should emit for unions with mixed literal internal types +48 | field15: Literal[1] | Literal["foo"] | Literal[True] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +49 | +50 | # Shouldn't emit for duplicate field types with same value; covered by Y016 + | + = help: Replace with a single `Literal` + +PYI030.py:51:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 1]` + | +50 | # Shouldn't emit for duplicate field types with same value; covered by Y016 +51 | field16: Literal[1] | Literal[1] # OK + | ^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +52 | +53 | # Shouldn't emit if in new parent type + | + = help: Replace with a single `Literal` + +PYI030.py:60:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` + | +59 | # Should respect name of literal type used +60 | field19: typing.Literal[1] | typing.Literal[2] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +61 | +62 | # Should emit in cases with newlines + | + = help: Replace with a single `Literal` + +PYI030.py:63:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` + | +62 | # Should emit in cases with newlines +63 | field20: typing.Union[ + | __________^ +64 | | Literal[ +65 | | 1 # test +66 | | ], +67 | | Literal[2], +68 | | ] # Error, newline and comment will not be emitted in message + | |_^ PYI030 +69 | +70 | # Should handle multiple unions with multiple members + | + = help: Replace with a single `Literal` + +PYI030.py:71:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3, 4]` + | +70 | # Should handle multiple unions with multiple members +71 | field21: Literal[1, 2] | Literal[3, 4] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +72 | +73 | # Should emit in cases with `typing.Union` instead of `|` + | + = help: Replace with a single `Literal` + +PYI030.py:74:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` + | +73 | # Should emit in cases with `typing.Union` instead of `|` +74 | field22: typing.Union[Literal[1], Literal[2]] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +75 | +76 | # Should emit in cases with `typing_extensions.Literal` + | + = help: Replace with a single `Literal` + +PYI030.py:77:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` + | +76 | # Should emit in cases with `typing_extensions.Literal` +77 | field23: typing_extensions.Literal[1] | typing_extensions.Literal[2] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +78 | +79 | # Should emit in cases with nested `typing.Union` + | + = help: Replace with a single `Literal` + +PYI030.py:80:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` + | +79 | # Should emit in cases with nested `typing.Union` +80 | field24: typing.Union[Literal[1], typing.Union[Literal[2], str]] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +81 | +82 | # Should emit in cases with mixed `typing.Union` and `|` + | + = help: Replace with a single `Literal` + +PYI030.py:83:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` + | +82 | # Should emit in cases with mixed `typing.Union` and `|` +83 | field25: typing.Union[Literal[1], Literal[2] | str] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +84 | +85 | # Should emit only once in cases with multiple nested `typing.Union` + | + = help: Replace with a single `Literal` + +PYI030.py:86:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3, 4]` + | +85 | # Should emit only once in cases with multiple nested `typing.Union` +86 | field24: typing.Union[Literal[1], typing.Union[Literal[2], typing.Union[Literal[3], Literal[4]]]] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +87 | +88 | # Should use the first literal subscript attribute when fixing + | + = help: Replace with a single `Literal` + +PYI030.py:89:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3, 4]` + | +88 | # Should use the first literal subscript attribute when fixing +89 | field25: typing.Union[typing_extensions.Literal[1], typing.Union[Literal[2], typing.Union[Literal[3], Literal[4]]], str] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 + | + = help: Replace with a single `Literal` diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI030_PYI030.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI030_PYI030.pyi.snap index 6e9214a8a4c43..ec113b46dd315 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI030_PYI030.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI030_PYI030.pyi.snap @@ -9,6 +9,7 @@ PYI030.pyi:9:9: PYI030 Multiple literal members in a union. Use a single literal 10 | 11 | # Should emit for union types in arguments. | + = help: Replace with a single `Literal` PYI030.pyi:12:17: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -17,6 +18,7 @@ PYI030.pyi:12:17: PYI030 Multiple literal members in a union. Use a single liter | ^^^^^^^^^^^^^^^^^^^^^^^ PYI030 13 | print(arg1) | + = help: Replace with a single `Literal` PYI030.pyi:17:16: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -25,6 +27,7 @@ PYI030.pyi:17:16: PYI030 Multiple literal members in a union. Use a single liter | ^^^^^^^^^^^^^^^^^^^^^^^ PYI030 18 | return "my Literal[1]ing" | + = help: Replace with a single `Literal` PYI030.pyi:22:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -34,6 +37,7 @@ PYI030.pyi:22:9: PYI030 Multiple literal members in a union. Use a single litera 23 | field4: str | Literal[1] | Literal[2] # Error 24 | field5: Literal[1] | str | Literal[2] # Error | + = help: Replace with a single `Literal` PYI030.pyi:23:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -44,6 +48,7 @@ PYI030.pyi:23:9: PYI030 Multiple literal members in a union. Use a single litera 24 | field5: Literal[1] | str | Literal[2] # Error 25 | field6: Literal[1] | bool | Literal[2] | str # Error | + = help: Replace with a single `Literal` PYI030.pyi:24:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -53,6 +58,7 @@ PYI030.pyi:24:9: PYI030 Multiple literal members in a union. Use a single litera | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 25 | field6: Literal[1] | bool | Literal[2] | str # Error | + = help: Replace with a single `Literal` PYI030.pyi:25:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -63,6 +69,7 @@ PYI030.pyi:25:9: PYI030 Multiple literal members in a union. Use a single litera 26 | 27 | # Should emit for non-type unions. | + = help: Replace with a single `Literal` PYI030.pyi:28:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -72,6 +79,7 @@ PYI030.pyi:28:10: PYI030 Multiple literal members in a union. Use a single liter 29 | 30 | # Should emit for parenthesized unions. | + = help: Replace with a single `Literal` PYI030.pyi:31:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -81,6 +89,7 @@ PYI030.pyi:31:9: PYI030 Multiple literal members in a union. Use a single litera 32 | 33 | # Should handle user parentheses when fixing. | + = help: Replace with a single `Literal` PYI030.pyi:34:9: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -89,6 +98,7 @@ PYI030.pyi:34:9: PYI030 Multiple literal members in a union. Use a single litera | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 35 | field10: (Literal[1] | str) | Literal[2] # Error | + = help: Replace with a single `Literal` PYI030.pyi:35:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -99,6 +109,7 @@ PYI030.pyi:35:10: PYI030 Multiple literal members in a union. Use a single liter 36 | 37 | # Should emit for union in generic parent type. | + = help: Replace with a single `Literal` PYI030.pyi:38:15: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -108,6 +119,7 @@ PYI030.pyi:38:15: PYI030 Multiple literal members in a union. Use a single liter 39 | 40 | # Should emit for unions with more than two cases | + = help: Replace with a single `Literal` PYI030.pyi:41:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3]` | @@ -116,6 +128,7 @@ PYI030.pyi:41:10: PYI030 Multiple literal members in a union. Use a single liter | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 42 | field13: Literal[1] | Literal[2] | Literal[3] | Literal[4] # Error | + = help: Replace with a single `Literal` PYI030.pyi:42:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3, 4]` | @@ -126,6 +139,7 @@ PYI030.pyi:42:10: PYI030 Multiple literal members in a union. Use a single liter 43 | 44 | # Should emit for unions with more than two cases, even if not directly adjacent | + = help: Replace with a single `Literal` PYI030.pyi:45:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3]` | @@ -135,6 +149,7 @@ PYI030.pyi:45:10: PYI030 Multiple literal members in a union. Use a single liter 46 | 47 | # Should emit for unions with mixed literal internal types | + = help: Replace with a single `Literal` PYI030.pyi:48:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, "foo", True]` | @@ -144,6 +159,7 @@ PYI030.pyi:48:10: PYI030 Multiple literal members in a union. Use a single liter 49 | 50 | # Shouldn't emit for duplicate field types with same value; covered by Y016 | + = help: Replace with a single `Literal` PYI030.pyi:51:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 1]` | @@ -153,6 +169,7 @@ PYI030.pyi:51:10: PYI030 Multiple literal members in a union. Use a single liter 52 | 53 | # Shouldn't emit if in new parent type | + = help: Replace with a single `Literal` PYI030.pyi:60:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -162,6 +179,7 @@ PYI030.pyi:60:10: PYI030 Multiple literal members in a union. Use a single liter 61 | 62 | # Should emit in cases with newlines | + = help: Replace with a single `Literal` PYI030.pyi:63:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -177,6 +195,7 @@ PYI030.pyi:63:10: PYI030 Multiple literal members in a union. Use a single liter 69 | 70 | # Should handle multiple unions with multiple members | + = help: Replace with a single `Literal` PYI030.pyi:71:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3, 4]` | @@ -186,6 +205,7 @@ PYI030.pyi:71:10: PYI030 Multiple literal members in a union. Use a single liter 72 | 73 | # Should emit in cases with `typing.Union` instead of `|` | + = help: Replace with a single `Literal` PYI030.pyi:74:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -195,6 +215,7 @@ PYI030.pyi:74:10: PYI030 Multiple literal members in a union. Use a single liter 75 | 76 | # Should emit in cases with `typing_extensions.Literal` | + = help: Replace with a single `Literal` PYI030.pyi:77:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -204,6 +225,7 @@ PYI030.pyi:77:10: PYI030 Multiple literal members in a union. Use a single liter 78 | 79 | # Should emit in cases with nested `typing.Union` | + = help: Replace with a single `Literal` PYI030.pyi:80:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -213,6 +235,7 @@ PYI030.pyi:80:10: PYI030 Multiple literal members in a union. Use a single liter 81 | 82 | # Should emit in cases with mixed `typing.Union` and `|` | + = help: Replace with a single `Literal` PYI030.pyi:83:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2]` | @@ -222,12 +245,24 @@ PYI030.pyi:83:10: PYI030 Multiple literal members in a union. Use a single liter 84 | 85 | # Should emit only once in cases with multiple nested `typing.Union` | + = help: Replace with a single `Literal` PYI030.pyi:86:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3, 4]` | 85 | # Should emit only once in cases with multiple nested `typing.Union` 86 | field24: typing.Union[Literal[1], typing.Union[Literal[2], typing.Union[Literal[3], Literal[4]]]] # Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 +87 | +88 | # Should use the first literal subscript attribute when fixing | + = help: Replace with a single `Literal` + +PYI030.pyi:89:10: PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[1, 2, 3, 4]` + | +88 | # Should use the first literal subscript attribute when fixing +89 | field25: typing.Union[typing_extensions.Literal[1], typing.Union[Literal[2], typing.Union[Literal[3], Literal[4]]], str] # Error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI030 + | + = help: Replace with a single `Literal` diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI042_PYI042.py.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI042_PYI042.py.snap index 1f80b9c9af969..539eb12d99a7f 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI042_PYI042.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI042_PYI042.py.snap @@ -29,4 +29,12 @@ PYI042.py:20:1: PYI042 Type alias `_snake_case_alias2` should be CamelCase 21 | Snake_case_alias: TypeAlias = int | float # PYI042, since not camel case | +PYI042.py:27:6: PYI042 Type alias `foo_bar` should be CamelCase + | +26 | # PEP 695 +27 | type foo_bar = int | str + | ^^^^^^^ PYI042 +28 | type FooBar = int | str + | + diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI042_PYI042.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI042_PYI042.pyi.snap index ab3c2fe98eeed..9d1d034c0018e 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI042_PYI042.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI042_PYI042.pyi.snap @@ -29,4 +29,12 @@ PYI042.pyi:20:1: PYI042 Type alias `_snake_case_alias2` should be CamelCase 21 | Snake_case_alias: TypeAlias = int | float # PYI042, since not camel case | +PYI042.pyi:27:6: PYI042 Type alias `foo_bar` should be CamelCase + | +26 | # PEP 695 +27 | type foo_bar = int | str + | ^^^^^^^ PYI042 +28 | type FooBar = int | str + | + diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI043_PYI043.py.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI043_PYI043.py.snap index 3dfc9c819b5e8..550ad122d17de 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI043_PYI043.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI043_PYI043.py.snap @@ -30,4 +30,12 @@ PYI043.py:12:1: PYI043 Private type alias `_PrivateAliasT3` should not be suffix 14 | ] # PYI043, since this ends in a T | +PYI043.py:26:6: PYI043 Private type alias `_FooT` should not be suffixed with `T` (the `T` suffix implies that an object is a `TypeVar`) + | +25 | # PEP 695 +26 | type _FooT = str | int + | ^^^^^ PYI043 +27 | type Foo = str | int + | + diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI043_PYI043.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI043_PYI043.pyi.snap index f856dc86ad88a..80fb8b4c19182 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI043_PYI043.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI043_PYI043.pyi.snap @@ -30,4 +30,12 @@ PYI043.pyi:12:1: PYI043 Private type alias `_PrivateAliasT3` should not be suffi 14 | ] # PYI043, since this ends in a T | +PYI043.pyi:26:6: PYI043 Private type alias `_FooT` should not be suffixed with `T` (the `T` suffix implies that an object is a `TypeVar`) + | +25 | # PEP 695 +26 | type _FooT = str | int + | ^^^^^ PYI043 +27 | type Foo = str | int + | + diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI050_PYI050.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI050_PYI050.pyi.snap index a0cb503548fca..caafc0254ea8c 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI050_PYI050.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI050_PYI050.pyi.snap @@ -28,6 +28,67 @@ PYI050.pyi:11:47: PYI050 Prefer `typing.Never` over `NoReturn` for argument anno 11 | def foo_no_return_pos_only(arg: int, /, arg2: NoReturn): ... # Error: PYI050 | ^^^^^^^^ PYI050 12 | def foo_never(arg: Never): ... +13 | def foo_args(*args: NoReturn): ... # Error: PYI050 + | + +PYI050.pyi:13:21: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations + | +11 | def foo_no_return_pos_only(arg: int, /, arg2: NoReturn): ... # Error: PYI050 +12 | def foo_never(arg: Never): ... +13 | def foo_args(*args: NoReturn): ... # Error: PYI050 + | ^^^^^^^^ PYI050 +14 | def foo_kwargs(**kwargs: NoReturn): ... # Error: PYI050 +15 | def foo_args_kwargs(*args: NoReturn, **kwargs: NoReturn): ... # Error: PYI050 + | + +PYI050.pyi:14:26: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations + | +12 | def foo_never(arg: Never): ... +13 | def foo_args(*args: NoReturn): ... # Error: PYI050 +14 | def foo_kwargs(**kwargs: NoReturn): ... # Error: PYI050 + | ^^^^^^^^ PYI050 +15 | def foo_args_kwargs(*args: NoReturn, **kwargs: NoReturn): ... # Error: PYI050 +16 | def foo_int_args(*args: int): ... + | + +PYI050.pyi:15:28: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations + | +13 | def foo_args(*args: NoReturn): ... # Error: PYI050 +14 | def foo_kwargs(**kwargs: NoReturn): ... # Error: PYI050 +15 | def foo_args_kwargs(*args: NoReturn, **kwargs: NoReturn): ... # Error: PYI050 + | ^^^^^^^^ PYI050 +16 | def foo_int_args(*args: int): ... +17 | def foo_int_kwargs(**kwargs: int): ... + | + +PYI050.pyi:15:48: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations + | +13 | def foo_args(*args: NoReturn): ... # Error: PYI050 +14 | def foo_kwargs(**kwargs: NoReturn): ... # Error: PYI050 +15 | def foo_args_kwargs(*args: NoReturn, **kwargs: NoReturn): ... # Error: PYI050 + | ^^^^^^^^ PYI050 +16 | def foo_int_args(*args: int): ... +17 | def foo_int_kwargs(**kwargs: int): ... + | + +PYI050.pyi:19:50: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations + | +17 | def foo_int_kwargs(**kwargs: int): ... +18 | def foo_int_args_kwargs(*args: int, **kwargs: int): ... +19 | def foo_int_args_no_return(*args: int, **kwargs: NoReturn): ... # Error: PYI050 + | ^^^^^^^^ PYI050 +20 | def foo_int_kwargs_no_return(*args: NoReturn, **kwargs: int): ... # Error: PYI050 +21 | def foo_args_never(*args: Never): ... + | + +PYI050.pyi:20:37: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations + | +18 | def foo_int_args_kwargs(*args: int, **kwargs: int): ... +19 | def foo_int_args_no_return(*args: int, **kwargs: NoReturn): ... # Error: PYI050 +20 | def foo_int_kwargs_no_return(*args: NoReturn, **kwargs: int): ... # Error: PYI050 + | ^^^^^^^^ PYI050 +21 | def foo_args_never(*args: Never): ... +22 | def foo_kwargs_never(**kwargs: Never): ... | diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap index 2e8fd1a1a3f5b..f0a6ebc9055fb 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap @@ -90,7 +90,7 @@ PYI053.pyi:30:14: PYI053 [*] String and bytes literals longer than 50 characters 30 | qux: bytes = b"51 character byte stringggggggggggggggggggggggggggg\xff" # Error: PYI053 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI053 31 | -32 | class Demo: +32 | ffoo: str = f"50 character stringggggggggggggggggggggggggggggggg" # OK | = help: Replace with `...` @@ -101,7 +101,28 @@ PYI053.pyi:30:14: PYI053 [*] String and bytes literals longer than 50 characters 30 |-qux: bytes = b"51 character byte stringggggggggggggggggggggggggggg\xff" # Error: PYI053 30 |+qux: bytes = ... # Error: PYI053 31 31 | -32 32 | class Demo: -33 33 | """Docstrings are excluded from this rule. Some padding.""" # OK +32 32 | ffoo: str = f"50 character stringggggggggggggggggggggggggggggggg" # OK +33 33 | + +PYI053.pyi:34:15: PYI053 [*] String and bytes literals longer than 50 characters are not permitted + | +32 | ffoo: str = f"50 character stringggggggggggggggggggggggggggggggg" # OK +33 | +34 | fbar: str = f"51 character stringgggggggggggggggggggggggggggggggg" # Error: PYI053 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI053 +35 | +36 | class Demo: + | + = help: Replace with `...` + +ℹ Safe fix +31 31 | +32 32 | ffoo: str = f"50 character stringggggggggggggggggggggggggggggggg" # OK +33 33 | +34 |-fbar: str = f"51 character stringgggggggggggggggggggggggggggggggg" # Error: PYI053 + 34 |+fbar: str = f"..." # Error: PYI053 +35 35 | +36 36 | class Demo: +37 37 | """Docstrings are excluded from this rule. Some padding.""" # OK diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs index 80a6181832a0a..dde7f269280b3 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs @@ -33,7 +33,7 @@ use super::unittest_assert::UnittestAssert; /// Checks for assertions that combine multiple independent conditions. /// /// ## Why is this bad? -/// Composite assertion statements are harder debug upon failure, as the +/// Composite assertion statements are harder to debug upon failure, as the /// failure message will not indicate which condition failed. /// /// ## Example diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs index e618fa3b5f018..9ac12913539d9 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs @@ -55,13 +55,28 @@ pub(super) fn is_empty_or_null_string(expr: &Expr) -> bool { match expr { Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => value.is_empty(), Expr::NoneLiteral(_) => true, - Expr::FString(ast::ExprFString { values, .. }) => { - values.iter().all(is_empty_or_null_string) + Expr::FString(ast::ExprFString { value, .. }) => { + value.iter().all(|f_string_part| match f_string_part { + ast::FStringPart::Literal(literal) => literal.is_empty(), + ast::FStringPart::FString(f_string) => f_string + .elements + .iter() + .all(is_empty_or_null_fstring_element), + }) } _ => false, } } +fn is_empty_or_null_fstring_element(element: &ast::FStringElement) -> bool { + match element { + ast::FStringElement::Literal(ast::FStringLiteralElement { value, .. }) => value.is_empty(), + ast::FStringElement::Expression(ast::FStringExpressionElement { expression, .. }) => { + is_empty_or_null_string(expression) + } + } +} + pub(super) fn split_names(names: &str) -> Vec<&str> { // Match the following pytest code: // [x.strip() for x in argnames.split(",") if x.strip()] diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs index 5d494ed82e04c..0f5a621f01eac 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs @@ -252,19 +252,17 @@ fn elts_to_csv(elts: &[Expr], generator: Generator) -> Option { return None; } - let node = Expr::StringLiteral(ast::ExprStringLiteral { + let node = Expr::from(ast::StringLiteral { value: elts.iter().fold(String::new(), |mut acc, elt| { if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = elt { if !acc.is_empty() { acc.push(','); } - acc.push_str(value.as_str()); + acc.push_str(value.to_str()); } acc }), - unicode: false, - implicit_concatenated: false, - range: TextRange::default(), + ..ast::StringLiteral::default() }); Some(generator.expr(&node)) } @@ -302,8 +300,8 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { let names_type = checker.settings.flake8_pytest_style.parametrize_names_type; match expr { - Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) => { - let names = split_names(string); + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { + let names = split_names(value.to_str()); if names.len() > 1 { match names_type { types::ParametrizeNameType::Tuple => { @@ -324,9 +322,9 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { elts: names .iter() .map(|name| { - Expr::StringLiteral(ast::ExprStringLiteral { + Expr::from(ast::StringLiteral { value: (*name).to_string(), - ..ast::ExprStringLiteral::default() + ..ast::StringLiteral::default() }) }) .collect(), @@ -357,9 +355,9 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { elts: names .iter() .map(|name| { - Expr::StringLiteral(ast::ExprStringLiteral { + Expr::from(ast::StringLiteral { value: (*name).to_string(), - ..ast::ExprStringLiteral::default() + ..ast::StringLiteral::default() }) }) .collect(), @@ -477,12 +475,11 @@ fn check_values(checker: &mut Checker, names: &Expr, values: &Expr) { .flake8_pytest_style .parametrize_values_row_type; - let is_multi_named = - if let Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) = &names { - split_names(string).len() > 1 - } else { - true - }; + let is_multi_named = if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = &names { + split_names(value.to_str()).len() > 1 + } else { + true + }; match values { Expr::List(ast::ExprList { elts, .. }) => { @@ -553,7 +550,7 @@ fn check_duplicates(checker: &mut Checker, values: &Expr) { element.range(), ); if let Some(prev) = prev { - let values_end = values.range().end() - TextSize::new(1); + let values_end = values.end() - TextSize::new(1); let previous_end = trailing_comma(prev, checker.locator().contents()).unwrap_or(values_end); let element_end = diff --git a/crates/ruff_linter/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs b/crates/ruff_linter/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs index 4a0bffc74bc7d..a056bbc755f8d 100644 --- a/crates/ruff_linter/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs +++ b/crates/ruff_linter/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs @@ -78,9 +78,7 @@ pub(crate) fn unnecessary_paren_on_raise_exception(checker: &mut Checker, expr: // `ctypes.WinError()` is a function, not a class. It's part of the standard library, so // we might as well get it right. - if exception_type - .as_ref() - .is_some_and(ExceptionType::is_builtin) + if exception_type.is_none() && checker .semantic() .resolve_call_path(func) diff --git a/crates/ruff_linter/src/rules/flake8_raise/snapshots/ruff_linter__rules__flake8_raise__tests__unnecessary-paren-on-raise-exception_RSE102.py.snap b/crates/ruff_linter/src/rules/flake8_raise/snapshots/ruff_linter__rules__flake8_raise__tests__unnecessary-paren-on-raise-exception_RSE102.py.snap index 37b632cc2563b..d1d89829c673f 100644 --- a/crates/ruff_linter/src/rules/flake8_raise/snapshots/ruff_linter__rules__flake8_raise__tests__unnecessary-paren-on-raise-exception_RSE102.py.snap +++ b/crates/ruff_linter/src/rules/flake8_raise/snapshots/ruff_linter__rules__flake8_raise__tests__unnecessary-paren-on-raise-exception_RSE102.py.snap @@ -266,6 +266,8 @@ RSE102.py:84:10: RSE102 [*] Unnecessary parentheses on raised exception 83 | # RSE102 84 | raise Foo() | ^^ RSE102 +85 | +86 | # OK | = help: Remove unnecessary parentheses @@ -275,5 +277,8 @@ RSE102.py:84:10: RSE102 [*] Unnecessary parentheses on raised exception 83 83 | # RSE102 84 |-raise Foo() 84 |+raise Foo +85 85 | +86 86 | # OK +87 87 | raise ctypes.WinError() diff --git a/crates/ruff_linter/src/rules/flake8_self/rules/private_member_access.rs b/crates/ruff_linter/src/rules/flake8_self/rules/private_member_access.rs index 543c4d36d7348..fdbf3e8def12b 100644 --- a/crates/ruff_linter/src/rules/flake8_self/rules/private_member_access.rs +++ b/crates/ruff_linter/src/rules/flake8_self/rules/private_member_access.rs @@ -66,6 +66,10 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) { return; }; + if checker.semantic().in_annotation() { + return; + } + if (attr.starts_with("__") && !attr.ends_with("__")) || (attr.starts_with('_') && !attr.starts_with("__")) { diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs index 4a3b5a7d524ab..5f2d278474cc2 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs @@ -161,19 +161,19 @@ pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Ex return; } - if is_lowercase_allowed(env_var) { + if is_lowercase_allowed(env_var.to_str()) { return; } - let capital_env_var = env_var.to_ascii_uppercase(); - if &capital_env_var == env_var { + let capital_env_var = env_var.to_str().to_ascii_uppercase(); + if capital_env_var == env_var.to_str() { return; } checker.diagnostics.push(Diagnostic::new( UncapitalizedEnvironmentVariables { expected: SourceCodeSnippet::new(capital_env_var), - actual: SourceCodeSnippet::new(env_var.clone()), + actual: SourceCodeSnippet::new(env_var.to_string()), }, arg.range(), )); @@ -197,35 +197,30 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) { if id != "os" || attr != "environ" { return; } - let Expr::StringLiteral(ast::ExprStringLiteral { - value: env_var, - unicode, - .. - }) = slice.as_ref() - else { + let Expr::StringLiteral(ast::ExprStringLiteral { value: env_var, .. }) = slice.as_ref() else { return; }; - if is_lowercase_allowed(env_var) { + if is_lowercase_allowed(env_var.to_str()) { return; } - let capital_env_var = env_var.to_ascii_uppercase(); - if &capital_env_var == env_var { + let capital_env_var = env_var.to_str().to_ascii_uppercase(); + if capital_env_var == env_var.to_str() { return; } let mut diagnostic = Diagnostic::new( UncapitalizedEnvironmentVariables { expected: SourceCodeSnippet::new(capital_env_var.clone()), - actual: SourceCodeSnippet::new(env_var.clone()), + actual: SourceCodeSnippet::new(env_var.to_string()), }, slice.range(), ); - let node = ast::ExprStringLiteral { + let node = ast::StringLiteral { value: capital_env_var, - unicode: *unicode, - ..ast::ExprStringLiteral::default() + unicode: env_var.is_unicode(), + ..ast::StringLiteral::default() }; let new_env_var = node.into(); diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs index e3dedd26a477c..fd1afd9d468db 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs @@ -1,3 +1,4 @@ +use ast::Expr; use log::error; use ruff_diagnostics::{Diagnostic, Fix}; @@ -24,6 +25,13 @@ use super::fix_with; /// will minimize the indentation depth of the code, making it more /// readable. /// +/// The following context managers are exempt when used as standalone +/// statements: +/// +/// - `anyio`.{`CancelScope`, `fail_after`, `move_on_after`} +/// - `asyncio`.{`timeout`, `timeout_at`} +/// - `trio`.{`fail_after`, `fail_at`, `move_on_after`, `move_on_at`} +/// /// ## Example /// ```python /// with A() as a: @@ -73,6 +81,38 @@ fn next_with(body: &[Stmt]) -> Option<(bool, &[WithItem], &[Stmt])> { Some((*is_async, items, body)) } +/// Check if `with_items` contains a single item which should not necessarily be +/// grouped with other items. +/// +/// For example: +/// ```python +/// async with asyncio.timeout(1): +/// with resource1(), resource2(): +/// ... +/// ``` +fn explicit_with_items(checker: &mut Checker, with_items: &[WithItem]) -> bool { + let [with_item] = with_items else { + return false; + }; + let Expr::Call(expr_call) = &with_item.context_expr else { + return false; + }; + checker + .semantic() + .resolve_call_path(&expr_call.func) + .is_some_and(|call_path| { + matches!( + call_path.as_slice(), + ["asyncio", "timeout" | "timeout_at"] + | ["anyio", "CancelScope" | "fail_after" | "move_on_after"] + | [ + "trio", + "fail_after" | "fail_at" | "move_on_after" | "move_on_at" + ] + ) + }) +} + /// SIM117 pub(crate) fn multiple_with_statements( checker: &mut Checker, @@ -111,6 +151,10 @@ pub(crate) fn multiple_with_statements( return; } + if explicit_with_items(checker, &with_stmt.items) || explicit_with_items(checker, items) { + return; + } + let Some(colon) = items.last().and_then(|item| { SimpleTokenizer::starts_at(item.end(), checker.locator().contents()) .skip_trivia() diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM117_SIM117.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM117_SIM117.py.snap index 5b71ad0883a2a..21af88e707913 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM117_SIM117.py.snap +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM117_SIM117.py.snap @@ -316,5 +316,28 @@ SIM117.py:126:1: SIM117 [*] Use a single `with` statement with multiple contexts 135 134 | 136 |- f"foo {f"bar {x}"} baz" 135 |+ f"foo {f"bar {x}"} baz" +137 136 | +138 137 | # Allow cascading for some statements. +139 138 | import anyio + +SIM117.py:163:1: SIM117 [*] Use a single `with` statement with multiple contexts instead of nested `with` statements + | +162 | # Do not supress combination, if a context manager is already combined with another. +163 | / async with asyncio.timeout(1), A(): +164 | | async with B(): + | |___________________^ SIM117 +165 | pass + | + = help: Combine `with` statements + +ℹ Unsafe fix +160 160 | pass +161 161 | +162 162 | # Do not supress combination, if a context manager is already combined with another. +163 |-async with asyncio.timeout(1), A(): +164 |- async with B(): +165 |- pass + 163 |+async with asyncio.timeout(1), A(), B(): + 164 |+ pass diff --git a/crates/ruff_linter/src/rules/flake8_trio/rules/zero_sleep_call.rs b/crates/ruff_linter/src/rules/flake8_trio/rules/zero_sleep_call.rs index aa583d0d67eaa..57caec4eec68c 100644 --- a/crates/ruff_linter/src/rules/flake8_trio/rules/zero_sleep_call.rs +++ b/crates/ruff_linter/src/rules/flake8_trio/rules/zero_sleep_call.rs @@ -1,7 +1,7 @@ use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::Stmt; use ruff_python_ast::{self as ast, Expr, ExprCall, Int}; +use ruff_python_semantic::analyze::typing::find_assigned_value; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -16,12 +16,18 @@ use crate::importer::ImportRequest; /// /// ## Example /// ```python +/// import trio +/// +/// /// async def func(): /// await trio.sleep(0) /// ``` /// /// Use instead: /// ```python +/// import trio +/// +/// /// async def func(): /// await trio.lowlevel.checkpoint() /// ``` @@ -65,30 +71,15 @@ pub(crate) fn zero_sleep_call(checker: &mut Checker, call: &ExprCall) { } } Expr::Name(ast::ExprName { id, .. }) => { - let scope = checker.semantic().current_scope(); - if let Some(binding_id) = scope.get(id) { - let binding = checker.semantic().binding(binding_id); - if binding.kind.is_assignment() || binding.kind.is_named_expr_assignment() { - if let Some(parent_id) = binding.source { - let parent = checker.semantic().statement(parent_id); - if let Stmt::Assign(ast::StmtAssign { value, .. }) - | Stmt::AnnAssign(ast::StmtAnnAssign { - value: Some(value), .. - }) - | Stmt::AugAssign(ast::StmtAugAssign { value, .. }) = parent - { - let Expr::NumberLiteral(ast::ExprNumberLiteral { value: num, .. }) = - value.as_ref() - else { - return; - }; - let Some(int) = num.as_int() else { return }; - if *int != Int::ZERO { - return; - } - } - } - } + let Some(value) = find_assigned_value(id, checker.semantic()) else { + return; + }; + let Expr::NumberLiteral(ast::ExprNumberLiteral { value: num, .. }) = value else { + return; + }; + let Some(int) = num.as_int() else { return }; + if *int != Int::ZERO { + return; } } _ => return, @@ -103,7 +94,7 @@ pub(crate) fn zero_sleep_call(checker: &mut Checker, call: &ExprCall) { )?; let reference_edit = Edit::range_replacement(format!("{binding}.checkpoint"), call.func.range()); - let arg_edit = Edit::range_deletion(call.arguments.range); + let arg_edit = Edit::range_replacement("()".to_string(), call.arguments.range()); Ok(Fix::safe_edits(import_edit, [reference_edit, arg_edit])) }); checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_trio/snapshots/ruff_linter__rules__flake8_trio__tests__TRIO115_TRIO115.py.snap b/crates/ruff_linter/src/rules/flake8_trio/snapshots/ruff_linter__rules__flake8_trio__tests__TRIO115_TRIO115.py.snap index 9e2fa6d2b5f5f..7710be928504a 100644 --- a/crates/ruff_linter/src/rules/flake8_trio/snapshots/ruff_linter__rules__flake8_trio__tests__TRIO115_TRIO115.py.snap +++ b/crates/ruff_linter/src/rules/flake8_trio/snapshots/ruff_linter__rules__flake8_trio__tests__TRIO115_TRIO115.py.snap @@ -17,7 +17,7 @@ TRIO115.py:5:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.s 3 3 | from trio import sleep 4 4 | 5 |- await trio.sleep(0) # TRIO115 - 5 |+ await trio.lowlevel.checkpoint # TRIO115 + 5 |+ await trio.lowlevel.checkpoint() # TRIO115 6 6 | await trio.sleep(1) # OK 7 7 | await trio.sleep(0, 1) # OK 8 8 | await trio.sleep(...) # OK @@ -38,7 +38,7 @@ TRIO115.py:11:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.s 9 9 | await trio.sleep() # OK 10 10 | 11 |- trio.sleep(0) # TRIO115 - 11 |+ trio.lowlevel.checkpoint # TRIO115 + 11 |+ trio.lowlevel.checkpoint() # TRIO115 12 12 | foo = 0 13 13 | trio.sleep(foo) # TRIO115 14 14 | trio.sleep(1) # OK @@ -59,7 +59,7 @@ TRIO115.py:13:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.s 11 11 | trio.sleep(0) # TRIO115 12 12 | foo = 0 13 |- trio.sleep(foo) # TRIO115 - 13 |+ trio.lowlevel.checkpoint # TRIO115 + 13 |+ trio.lowlevel.checkpoint() # TRIO115 14 14 | trio.sleep(1) # OK 15 15 | time.sleep(0) # OK 16 16 | @@ -80,28 +80,232 @@ TRIO115.py:17:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.s 15 15 | time.sleep(0) # OK 16 16 | 17 |- sleep(0) # TRIO115 - 17 |+ trio.lowlevel.checkpoint # TRIO115 + 17 |+ trio.lowlevel.checkpoint() # TRIO115 18 18 | 19 19 | bar = "bar" 20 20 | trio.sleep(bar) -TRIO115.py:30:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` +TRIO115.py:23:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` | -29 | def func(): -30 | sleep(0) # TRIO115 - | ^^^^^^^^ TRIO115 +22 | x, y = 0, 2000 +23 | trio.sleep(x) # TRIO115 + | ^^^^^^^^^^^^^ TRIO115 +24 | trio.sleep(y) # OK + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +20 20 | trio.sleep(bar) +21 21 | +22 22 | x, y = 0, 2000 +23 |- trio.sleep(x) # TRIO115 + 23 |+ trio.lowlevel.checkpoint() # TRIO115 +24 24 | trio.sleep(y) # OK +25 25 | +26 26 | (a, b, [c, (d, e)]) = (1, 2, (0, [4, 0])) + +TRIO115.py:27:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +26 | (a, b, [c, (d, e)]) = (1, 2, (0, [4, 0])) +27 | trio.sleep(c) # TRIO115 + | ^^^^^^^^^^^^^ TRIO115 +28 | trio.sleep(d) # OK +29 | trio.sleep(e) # TRIO115 | = help: Replace with `trio.lowlevel.checkpoint()` ℹ Safe fix -24 24 | trio.run(trio.sleep(0)) # TRIO115 +24 24 | trio.sleep(y) # OK 25 25 | -26 26 | -27 |-from trio import Event, sleep - 27 |+from trio import Event, sleep, lowlevel -28 28 | -29 29 | def func(): -30 |- sleep(0) # TRIO115 - 30 |+ lowlevel.checkpoint # TRIO115 +26 26 | (a, b, [c, (d, e)]) = (1, 2, (0, [4, 0])) +27 |- trio.sleep(c) # TRIO115 + 27 |+ trio.lowlevel.checkpoint() # TRIO115 +28 28 | trio.sleep(d) # OK +29 29 | trio.sleep(e) # TRIO115 +30 30 | + +TRIO115.py:29:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +27 | trio.sleep(c) # TRIO115 +28 | trio.sleep(d) # OK +29 | trio.sleep(e) # TRIO115 + | ^^^^^^^^^^^^^ TRIO115 +30 | +31 | m_x, m_y = 0 + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +26 26 | (a, b, [c, (d, e)]) = (1, 2, (0, [4, 0])) +27 27 | trio.sleep(c) # TRIO115 +28 28 | trio.sleep(d) # OK +29 |- trio.sleep(e) # TRIO115 + 29 |+ trio.lowlevel.checkpoint() # TRIO115 +30 30 | +31 31 | m_x, m_y = 0 +32 32 | trio.sleep(m_y) # OK + +TRIO115.py:36:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +35 | m_a = m_b = 0 +36 | trio.sleep(m_a) # TRIO115 + | ^^^^^^^^^^^^^^^ TRIO115 +37 | trio.sleep(m_b) # TRIO115 + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +33 33 | trio.sleep(m_x) # OK +34 34 | +35 35 | m_a = m_b = 0 +36 |- trio.sleep(m_a) # TRIO115 + 36 |+ trio.lowlevel.checkpoint() # TRIO115 +37 37 | trio.sleep(m_b) # TRIO115 +38 38 | +39 39 | m_c = (m_d, m_e) = (0, 0) + +TRIO115.py:37:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +35 | m_a = m_b = 0 +36 | trio.sleep(m_a) # TRIO115 +37 | trio.sleep(m_b) # TRIO115 + | ^^^^^^^^^^^^^^^ TRIO115 +38 | +39 | m_c = (m_d, m_e) = (0, 0) + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +34 34 | +35 35 | m_a = m_b = 0 +36 36 | trio.sleep(m_a) # TRIO115 +37 |- trio.sleep(m_b) # TRIO115 + 37 |+ trio.lowlevel.checkpoint() # TRIO115 +38 38 | +39 39 | m_c = (m_d, m_e) = (0, 0) +40 40 | trio.sleep(m_c) # OK + +TRIO115.py:41:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +39 | m_c = (m_d, m_e) = (0, 0) +40 | trio.sleep(m_c) # OK +41 | trio.sleep(m_d) # TRIO115 + | ^^^^^^^^^^^^^^^ TRIO115 +42 | trio.sleep(m_e) # TRIO115 + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +38 38 | +39 39 | m_c = (m_d, m_e) = (0, 0) +40 40 | trio.sleep(m_c) # OK +41 |- trio.sleep(m_d) # TRIO115 + 41 |+ trio.lowlevel.checkpoint() # TRIO115 +42 42 | trio.sleep(m_e) # TRIO115 +43 43 | +44 44 | + +TRIO115.py:42:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +40 | trio.sleep(m_c) # OK +41 | trio.sleep(m_d) # TRIO115 +42 | trio.sleep(m_e) # TRIO115 + | ^^^^^^^^^^^^^^^ TRIO115 + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +39 39 | m_c = (m_d, m_e) = (0, 0) +40 40 | trio.sleep(m_c) # OK +41 41 | trio.sleep(m_d) # TRIO115 +42 |- trio.sleep(m_e) # TRIO115 + 42 |+ trio.lowlevel.checkpoint() # TRIO115 +43 43 | +44 44 | +45 45 | def func(): + +TRIO115.py:48:14: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +46 | import trio +47 | +48 | trio.run(trio.sleep(0)) # TRIO115 + | ^^^^^^^^^^^^^ TRIO115 + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +45 45 | def func(): +46 46 | import trio +47 47 | +48 |- trio.run(trio.sleep(0)) # TRIO115 + 48 |+ trio.run(trio.lowlevel.checkpoint()) # TRIO115 +49 49 | +50 50 | +51 51 | from trio import Event, sleep + +TRIO115.py:55:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +54 | def func(): +55 | sleep(0) # TRIO115 + | ^^^^^^^^ TRIO115 + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +48 48 | trio.run(trio.sleep(0)) # TRIO115 +49 49 | +50 50 | +51 |-from trio import Event, sleep + 51 |+from trio import Event, sleep, lowlevel +52 52 | +53 53 | +54 54 | def func(): +55 |- sleep(0) # TRIO115 + 55 |+ lowlevel.checkpoint() # TRIO115 +56 56 | +57 57 | +58 58 | async def func(): + +TRIO115.py:59:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +58 | async def func(): +59 | await sleep(seconds=0) # TRIO115 + | ^^^^^^^^^^^^^^^^ TRIO115 + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +48 48 | trio.run(trio.sleep(0)) # TRIO115 +49 49 | +50 50 | +51 |-from trio import Event, sleep + 51 |+from trio import Event, sleep, lowlevel +52 52 | +53 53 | +54 54 | def func(): +-------------------------------------------------------------------------------- +56 56 | +57 57 | +58 58 | async def func(): +59 |- await sleep(seconds=0) # TRIO115 + 59 |+ await lowlevel.checkpoint() # TRIO115 +60 60 | +61 61 | +62 62 | def func(): + +TRIO115.py:66:9: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)` + | +65 | if (walrus := 0) == 0: +66 | trio.sleep(walrus) # TRIO115 + | ^^^^^^^^^^^^^^^^^^ TRIO115 + | + = help: Replace with `trio.lowlevel.checkpoint()` + +ℹ Safe fix +63 63 | import trio +64 64 | +65 65 | if (walrus := 0) == 0: +66 |- trio.sleep(walrus) # TRIO115 + 66 |+ trio.lowlevel.checkpoint() # TRIO115 diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs b/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs index d07fe2d6cb1f2..1f548896057b9 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs @@ -1,10 +1,34 @@ +use anyhow::Result; + +use ruff_diagnostics::Edit; use ruff_python_ast::call_path::from_qualified_name; -use ruff_python_ast::helpers::{map_callable, map_subscript}; -use ruff_python_ast::{self as ast}; -use ruff_python_semantic::{Binding, BindingId, BindingKind, ScopeKind, SemanticModel}; -use rustc_hash::FxHashSet; +use ruff_python_ast::helpers::map_callable; +use ruff_python_ast::{self as ast, Expr}; +use ruff_python_codegen::{Generator, Stylist}; +use ruff_python_semantic::{ + analyze, Binding, BindingKind, NodeId, ResolvedReference, SemanticModel, +}; +use ruff_source_file::Locator; +use ruff_text_size::Ranged; + +use crate::rules::flake8_type_checking::settings::Settings; + +/// Returns `true` if the [`ResolvedReference`] is in a typing-only context _or_ a runtime-evaluated +/// context (with quoting enabled). +pub(crate) fn is_typing_reference(reference: &ResolvedReference, settings: &Settings) -> bool { + reference.in_type_checking_block() + || reference.in_typing_only_annotation() + || reference.in_complex_string_type_definition() + || reference.in_simple_string_type_definition() + || (settings.quote_annotations && reference.in_runtime_evaluated_annotation()) +} -pub(crate) fn is_valid_runtime_import(binding: &Binding, semantic: &SemanticModel) -> bool { +/// Returns `true` if the [`Binding`] represents a runtime-required import. +pub(crate) fn is_valid_runtime_import( + binding: &Binding, + semantic: &SemanticModel, + settings: &Settings, +) -> bool { if matches!( binding.kind, BindingKind::Import(..) | BindingKind::FromImport(..) | BindingKind::SubmoduleImport(..) @@ -12,85 +36,49 @@ pub(crate) fn is_valid_runtime_import(binding: &Binding, semantic: &SemanticMode binding.context.is_runtime() && binding .references() - .any(|reference_id| semantic.reference(reference_id).context().is_runtime()) + .map(|reference_id| semantic.reference(reference_id)) + .any(|reference| !is_typing_reference(reference, settings)) } else { false } } -pub(crate) fn runtime_evaluated( +pub(crate) fn runtime_required_class( + class_def: &ast::StmtClassDef, base_classes: &[String], decorators: &[String], semantic: &SemanticModel, ) -> bool { - if !base_classes.is_empty() { - if runtime_evaluated_base_class(base_classes, semantic) { - return true; - } + if runtime_required_base_class(class_def, base_classes, semantic) { + return true; } - if !decorators.is_empty() { - if runtime_evaluated_decorators(decorators, semantic) { - return true; - } + if runtime_required_decorators(class_def, decorators, semantic) { + return true; } false } -fn runtime_evaluated_base_class(base_classes: &[String], semantic: &SemanticModel) -> bool { - fn inner( - class_def: &ast::StmtClassDef, - base_classes: &[String], - semantic: &SemanticModel, - seen: &mut FxHashSet, - ) -> bool { - class_def.bases().iter().any(|expr| { - // If the base class is itself runtime-evaluated, then this is too. - // Ex) `class Foo(BaseModel): ...` - if semantic - .resolve_call_path(map_subscript(expr)) - .is_some_and(|call_path| { - base_classes - .iter() - .any(|base_class| from_qualified_name(base_class) == call_path) - }) - { - return true; - } - - // If the base class extends a runtime-evaluated class, then this does too. - // Ex) `class Bar(BaseModel): ...; class Foo(Bar): ...` - if let Some(id) = semantic.lookup_attribute(map_subscript(expr)) { - if seen.insert(id) { - let binding = semantic.binding(id); - if let Some(base_class) = binding - .kind - .as_class_definition() - .map(|id| &semantic.scopes[*id]) - .and_then(|scope| scope.kind.as_class()) - { - if inner(base_class, base_classes, semantic, seen) { - return true; - } - } - } - } - false - }) - } - - semantic - .current_scope() - .kind - .as_class() - .is_some_and(|class_def| { - inner(class_def, base_classes, semantic, &mut FxHashSet::default()) - }) +/// Return `true` if a class is a subclass of a runtime-required base class. +fn runtime_required_base_class( + class_def: &ast::StmtClassDef, + base_classes: &[String], + semantic: &SemanticModel, +) -> bool { + analyze::class::any_over_body(class_def, semantic, &|call_path| { + base_classes + .iter() + .any(|base_class| from_qualified_name(base_class) == call_path) + }) } -fn runtime_evaluated_decorators(decorators: &[String], semantic: &SemanticModel) -> bool { - let ScopeKind::Class(class_def) = &semantic.current_scope().kind else { +fn runtime_required_decorators( + class_def: &ast::StmtClassDef, + decorators: &[String], + semantic: &SemanticModel, +) -> bool { + if decorators.is_empty() { return false; - }; + } class_def.decorator_list.iter().any(|decorator| { semantic @@ -102,3 +90,148 @@ fn runtime_evaluated_decorators(decorators: &[String], semantic: &SemanticModel) }) }) } + +/// Returns `true` if a function is registered as a `singledispatch` interface. +/// +/// For example, `fun` below is a `singledispatch` interface: +/// ```python +/// from functools import singledispatch +/// +/// @singledispatch +/// def fun(arg, verbose=False): +/// ... +/// ``` +pub(crate) fn is_singledispatch_interface( + function_def: &ast::StmtFunctionDef, + semantic: &SemanticModel, +) -> bool { + function_def.decorator_list.iter().any(|decorator| { + semantic + .resolve_call_path(&decorator.expression) + .is_some_and(|call_path| { + matches!(call_path.as_slice(), ["functools", "singledispatch"]) + }) + }) +} + +/// Returns `true` if a function is registered as a `singledispatch` implementation. +/// +/// For example, `_` below is a `singledispatch` implementation: +/// For example: +/// ```python +/// from functools import singledispatch +/// +/// @singledispatch +/// def fun(arg, verbose=False): +/// ... +/// +/// @fun.register +/// def _(arg: int, verbose=False): +/// ... +/// ``` +pub(crate) fn is_singledispatch_implementation( + function_def: &ast::StmtFunctionDef, + semantic: &SemanticModel, +) -> bool { + function_def.decorator_list.iter().any(|decorator| { + let Expr::Attribute(attribute) = &decorator.expression else { + return false; + }; + + if attribute.attr.as_str() != "register" { + return false; + }; + + let Some(id) = semantic.lookup_attribute(attribute.value.as_ref()) else { + return false; + }; + + let binding = semantic.binding(id); + let Some(function_def) = binding + .kind + .as_function_definition() + .map(|id| &semantic.scopes[*id]) + .and_then(|scope| scope.kind.as_function()) + else { + return false; + }; + + is_singledispatch_interface(function_def, semantic) + }) +} + +/// Wrap a type annotation in quotes. +/// +/// This requires more than just wrapping the reference itself in quotes. For example: +/// - When quoting `Series` in `Series[pd.Timestamp]`, we want `"Series[pd.Timestamp]"`. +/// - When quoting `kubernetes` in `kubernetes.SecurityContext`, we want `"kubernetes.SecurityContext"`. +/// - When quoting `Series` in `Series["pd.Timestamp"]`, we want `"Series[pd.Timestamp]"`. (This is currently unsupported.) +/// - When quoting `Series` in `Series[Literal["pd.Timestamp"]]`, we want `"Series[Literal['pd.Timestamp']]"`. (This is currently unsupported.) +/// +/// In general, when expanding a component of a call chain, we want to quote the entire call chain. +pub(crate) fn quote_annotation( + node_id: NodeId, + semantic: &SemanticModel, + locator: &Locator, + stylist: &Stylist, + generator: Generator, +) -> Result { + let expr = semantic.expression(node_id).expect("Expression not found"); + if let Some(parent_id) = semantic.parent_expression_id(node_id) { + match semantic.expression(parent_id) { + Some(Expr::Subscript(parent)) => { + if expr == parent.value.as_ref() { + // If we're quoting the value of a subscript, we need to quote the entire + // expression. For example, when quoting `DataFrame` in `DataFrame[int]`, we + // should generate `"DataFrame[int]"`. + return quote_annotation(parent_id, semantic, locator, stylist, generator); + } + } + Some(Expr::Attribute(parent)) => { + if expr == parent.value.as_ref() { + // If we're quoting the value of an attribute, we need to quote the entire + // expression. For example, when quoting `DataFrame` in `pd.DataFrame`, we + // should generate `"pd.DataFrame"`. + return quote_annotation(parent_id, semantic, locator, stylist, generator); + } + } + Some(Expr::Call(parent)) => { + if expr == parent.func.as_ref() { + // If we're quoting the function of a call, we need to quote the entire + // expression. For example, when quoting `DataFrame` in `DataFrame()`, we + // should generate `"DataFrame()"`. + return quote_annotation(parent_id, semantic, locator, stylist, generator); + } + } + Some(Expr::BinOp(parent)) => { + if parent.op.is_bit_or() { + // If we're quoting the left or right side of a binary operation, we need to + // quote the entire expression. For example, when quoting `DataFrame` in + // `DataFrame | Series`, we should generate `"DataFrame | Series"`. + return quote_annotation(parent_id, semantic, locator, stylist, generator); + } + } + _ => {} + } + } + + // If the annotation already contains a quote, avoid attempting to re-quote it. For example: + // ```python + // from typing import Literal + // + // Set[Literal["Foo"]] + // ``` + let text = locator.slice(expr); + if text.contains('\'') || text.contains('"') { + return Err(anyhow::anyhow!("Annotation already contains a quote")); + } + + // Quote the entire expression. + let quote = stylist.quote(); + let annotation = generator.expr(expr); + + Ok(Edit::range_replacement( + format!("{quote}{annotation}{quote}"), + expr.range(), + )) +} diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/imports.rs b/crates/ruff_linter/src/rules/flake8_type_checking/imports.rs new file mode 100644 index 0000000000000..92c65cf275e1c --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_type_checking/imports.rs @@ -0,0 +1,22 @@ +use ruff_python_semantic::{AnyImport, Binding, ResolvedReferenceId}; +use ruff_text_size::{Ranged, TextRange}; + +/// An import with its surrounding context. +pub(crate) struct ImportBinding<'a> { + /// The qualified name of the import (e.g., `typing.List` for `from typing import List`). + pub(crate) import: AnyImport<'a>, + /// The binding for the imported symbol. + pub(crate) binding: &'a Binding<'a>, + /// The first reference to the imported symbol. + pub(crate) reference_id: ResolvedReferenceId, + /// The trimmed range of the import (e.g., `List` in `from typing import List`). + pub(crate) range: TextRange, + /// The range of the import's parent statement. + pub(crate) parent_range: Option, +} + +impl Ranged for ImportBinding<'_> { + fn range(&self) -> TextRange { + self.range + } +} diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs b/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs index 97e9ad7cd4af0..5e5a05cb6ff0e 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs @@ -1,5 +1,6 @@ //! Rules from [flake8-type-checking](https://pypi.org/project/flake8-type-checking/). pub(crate) mod helpers; +mod imports; pub(crate) mod rules; pub mod settings; @@ -33,10 +34,13 @@ mod tests { #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_7.py"))] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_8.py"))] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_9.py"))] + #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("quote.py"))] #[test_case(Rule::TypingOnlyFirstPartyImport, Path::new("TCH001.py"))] #[test_case(Rule::TypingOnlyStandardLibraryImport, Path::new("TCH003.py"))] #[test_case(Rule::TypingOnlyStandardLibraryImport, Path::new("snapshot.py"))] #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("TCH002.py"))] + #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("quote.py"))] + #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("singledispatch.py"))] #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("strict.py"))] #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("typing_modules_1.py"))] #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("typing_modules_2.py"))] @@ -50,6 +54,24 @@ mod tests { Ok(()) } + #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("quote.py"))] + #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("quote.py"))] + fn quote(rule_code: Rule, path: &Path) -> Result<()> { + let snapshot = format!("quote_{}_{}", rule_code.as_ref(), path.to_string_lossy()); + let diagnostics = test_path( + Path::new("flake8_type_checking").join(path).as_path(), + &settings::LinterSettings { + flake8_type_checking: super::settings::Settings { + quote_annotations: true, + ..Default::default() + }, + ..settings::LinterSettings::for_rule(rule_code) + }, + )?; + assert_messages!(snapshot, diagnostics); + Ok(()) + } + #[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("strict.py"))] fn strict(rule_code: Rule, path: &Path) -> Result<()> { let diagnostics = test_path( @@ -108,7 +130,7 @@ mod tests { Path::new("flake8_type_checking").join(path).as_path(), &settings::LinterSettings { flake8_type_checking: super::settings::Settings { - runtime_evaluated_base_classes: vec![ + runtime_required_base_classes: vec![ "pydantic.BaseModel".to_string(), "sqlalchemy.orm.DeclarativeBase".to_string(), ], @@ -139,7 +161,7 @@ mod tests { Path::new("flake8_type_checking").join(path).as_path(), &settings::LinterSettings { flake8_type_checking: super::settings::Settings { - runtime_evaluated_decorators: vec![ + runtime_required_decorators: vec![ "attrs.define".to_string(), "attrs.frozen".to_string(), ], @@ -164,7 +186,7 @@ mod tests { Path::new("flake8_type_checking").join(path).as_path(), &settings::LinterSettings { flake8_type_checking: super::settings::Settings { - runtime_evaluated_base_classes: vec!["module.direct.MyBaseClass".to_string()], + runtime_required_base_classes: vec!["module.direct.MyBaseClass".to_string()], ..Default::default() }, ..settings::LinterSettings::for_rule(rule_code) diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs b/crates/ruff_linter/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs index dea0f4007e0cd..7f43ebbfd548d 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs @@ -1,17 +1,20 @@ use std::borrow::Cow; use anyhow::Result; +use itertools::Itertools; use rustc_hash::FxHashMap; use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_semantic::{AnyImport, Imported, NodeId, ResolvedReferenceId, Scope}; -use ruff_text_size::{Ranged, TextRange}; +use ruff_python_semantic::{Imported, NodeId, Scope}; +use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::codes::Rule; use crate::fix; use crate::importer::ImportedMembers; +use crate::rules::flake8_type_checking::helpers::quote_annotation; +use crate::rules::flake8_type_checking::imports::ImportBinding; /// ## What it does /// Checks for runtime imports defined in a type-checking block. @@ -20,6 +23,10 @@ use crate::importer::ImportedMembers; /// The type-checking block is not executed at runtime, so the import will not /// be available at runtime. /// +/// If [`flake8-type-checking.quote-annotations`] is set to `true`, +/// annotations will be wrapped in quotes if doing so would enable the +/// corresponding import to remain in the type-checking block. +/// /// ## Example /// ```python /// from typing import TYPE_CHECKING @@ -41,11 +48,15 @@ use crate::importer::ImportedMembers; /// foo.bar() /// ``` /// +/// ## Options +/// - `flake8-type-checking.quote-annotations` +/// /// ## References /// - [PEP 535](https://peps.python.org/pep-0563/#runtime-annotation-resolution-and-type-checking) #[violation] pub struct RuntimeImportInTypeCheckingBlock { qualified_name: String, + strategy: Strategy, } impl Violation for RuntimeImportInTypeCheckingBlock { @@ -53,17 +64,39 @@ impl Violation for RuntimeImportInTypeCheckingBlock { #[derive_message_formats] fn message(&self) -> String { - let RuntimeImportInTypeCheckingBlock { qualified_name } = self; - format!( - "Move import `{qualified_name}` out of type-checking block. Import is used for more than type hinting." - ) + let Self { + qualified_name, + strategy, + } = self; + match strategy { + Strategy::MoveImport => format!( + "Move import `{qualified_name}` out of type-checking block. Import is used for more than type hinting." + ), + Strategy::QuoteUsages => format!( + "Quote references to `{qualified_name}`. Import is in a type-checking block." + ), + } } fn fix_title(&self) -> Option { - Some("Move out of type-checking block".to_string()) + let Self { strategy, .. } = self; + match strategy { + Strategy::MoveImport => Some("Move out of type-checking block".to_string()), + Strategy::QuoteUsages => Some("Quote references".to_string()), + } } } +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +enum Action { + /// The import should be moved out of the type-checking block. + Move, + /// All usages of the import should be wrapped in quotes. + Quote, + /// The import should be ignored. + Ignore, +} + /// TCH004 pub(crate) fn runtime_import_in_type_checking_block( checker: &Checker, @@ -71,8 +104,7 @@ pub(crate) fn runtime_import_in_type_checking_block( diagnostics: &mut Vec, ) { // Collect all runtime imports by statement. - let mut errors_by_statement: FxHashMap> = FxHashMap::default(); - let mut ignores_by_statement: FxHashMap> = FxHashMap::default(); + let mut actions: FxHashMap<(NodeId, Action), Vec> = FxHashMap::default(); for binding_id in scope.binding_ids() { let binding = checker.semantic().binding(binding_id); @@ -101,6 +133,7 @@ pub(crate) fn runtime_import_in_type_checking_block( let import = ImportBinding { import, reference_id, + binding, range: binding.range(), parent_range: binding.parent_range(checker.semantic()), }; @@ -113,86 +146,152 @@ pub(crate) fn runtime_import_in_type_checking_block( ) }) { - ignores_by_statement - .entry(node_id) + actions + .entry((node_id, Action::Ignore)) .or_default() .push(import); } else { - errors_by_statement.entry(node_id).or_default().push(import); + // Determine whether the member should be fixed by moving the import out of the + // type-checking block, or by quoting its references. + if checker.settings.flake8_type_checking.quote_annotations + && binding.references().all(|reference_id| { + let reference = checker.semantic().reference(reference_id); + reference.context().is_typing() + || reference.in_runtime_evaluated_annotation() + }) + { + actions + .entry((node_id, Action::Quote)) + .or_default() + .push(import); + } else { + actions + .entry((node_id, Action::Move)) + .or_default() + .push(import); + } } } } - // Generate a diagnostic for every import, but share a fix across all imports within the same - // statement (excluding those that are ignored). - for (node_id, imports) in errors_by_statement { - let fix = fix_imports(checker, node_id, &imports).ok(); - - for ImportBinding { - import, - range, - parent_range, - .. - } in imports - { - let mut diagnostic = Diagnostic::new( - RuntimeImportInTypeCheckingBlock { - qualified_name: import.qualified_name(), - }, - range, - ); - if let Some(range) = parent_range { - diagnostic.set_parent(range.start()); + for ((node_id, action), imports) in actions { + match action { + // Generate a diagnostic for every import, but share a fix across all imports within the same + // statement (excluding those that are ignored). + Action::Move => { + let fix = move_imports(checker, node_id, &imports).ok(); + + for ImportBinding { + import, + range, + parent_range, + .. + } in imports + { + let mut diagnostic = Diagnostic::new( + RuntimeImportInTypeCheckingBlock { + qualified_name: import.qualified_name(), + strategy: Strategy::MoveImport, + }, + range, + ); + if let Some(range) = parent_range { + diagnostic.set_parent(range.start()); + } + if let Some(fix) = fix.as_ref() { + diagnostic.set_fix(fix.clone()); + } + diagnostics.push(diagnostic); + } } - if let Some(fix) = fix.as_ref() { - diagnostic.set_fix(fix.clone()); + + // Generate a diagnostic for every import, but share a fix across all imports within the same + // statement (excluding those that are ignored). + Action::Quote => { + let fix = quote_imports(checker, node_id, &imports).ok(); + + for ImportBinding { + import, + range, + parent_range, + .. + } in imports + { + let mut diagnostic = Diagnostic::new( + RuntimeImportInTypeCheckingBlock { + qualified_name: import.qualified_name(), + strategy: Strategy::QuoteUsages, + }, + range, + ); + if let Some(range) = parent_range { + diagnostic.set_parent(range.start()); + } + if let Some(fix) = fix.as_ref() { + diagnostic.set_fix(fix.clone()); + } + diagnostics.push(diagnostic); + } } - diagnostics.push(diagnostic); - } - } - // Separately, generate a diagnostic for every _ignored_ import, to ensure that the - // suppression comments aren't marked as unused. - for ImportBinding { - import, - range, - parent_range, - .. - } in ignores_by_statement.into_values().flatten() - { - let mut diagnostic = Diagnostic::new( - RuntimeImportInTypeCheckingBlock { - qualified_name: import.qualified_name(), - }, - range, - ); - if let Some(range) = parent_range { - diagnostic.set_parent(range.start()); + // Separately, generate a diagnostic for every _ignored_ import, to ensure that the + // suppression comments aren't marked as unused. + Action::Ignore => { + for ImportBinding { + import, + range, + parent_range, + .. + } in imports + { + let mut diagnostic = Diagnostic::new( + RuntimeImportInTypeCheckingBlock { + qualified_name: import.qualified_name(), + strategy: Strategy::MoveImport, + }, + range, + ); + if let Some(range) = parent_range { + diagnostic.set_parent(range.start()); + } + diagnostics.push(diagnostic); + } + } } - diagnostics.push(diagnostic); } } -/// A runtime-required import with its surrounding context. -struct ImportBinding<'a> { - /// The qualified name of the import (e.g., `typing.List` for `from typing import List`). - import: AnyImport<'a>, - /// The first reference to the imported symbol. - reference_id: ResolvedReferenceId, - /// The trimmed range of the import (e.g., `List` in `from typing import List`). - range: TextRange, - /// The range of the import's parent statement. - parent_range: Option, -} +/// Generate a [`Fix`] to quote runtime usages for imports in a type-checking block. +fn quote_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> Result { + let quote_reference_edits = imports + .iter() + .flat_map(|ImportBinding { binding, .. }| { + binding.references.iter().filter_map(|reference_id| { + let reference = checker.semantic().reference(*reference_id); + if reference.context().is_runtime() { + Some(quote_annotation( + reference.expression_id()?, + checker.semantic(), + checker.locator(), + checker.stylist(), + checker.generator(), + )) + } else { + None + } + }) + }) + .collect::>>()?; -impl Ranged for ImportBinding<'_> { - fn range(&self) -> TextRange { - self.range - } + let mut rest = quote_reference_edits.into_iter().unique(); + let head = rest.next().expect("Expected at least one reference"); + Ok(Fix::unsafe_edits(head, rest).isolate(Checker::isolation( + checker.semantic().parent_statement_id(node_id), + ))) } /// Generate a [`Fix`] to remove runtime imports from a type-checking block. -fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> Result { +fn move_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> Result { let statement = checker.semantic().statement(node_id); let parent = checker.semantic().parent_statement(node_id); @@ -236,3 +335,18 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> ), ) } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Strategy { + /// The import should be moved out of the type-checking block. + /// + /// This is required when at least one reference to the symbol is in a runtime-required context. + /// For example, given `from foo import Bar`, `x = Bar()` would be runtime-required. + MoveImport, + /// All usages of the import should be wrapped in quotes. + /// + /// This is acceptable when all references to the symbol are in a runtime-evaluated, but not + /// runtime-required context. For example, given `from foo import Bar`, `x: Bar` would be + /// runtime-evaluated, but not runtime-required. + QuoteUsages, +} diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs b/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs index 1ce6336d3b158..2ad9753362d11 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs @@ -1,17 +1,20 @@ use std::borrow::Cow; use anyhow::Result; +use itertools::Itertools; use rustc_hash::FxHashMap; use ruff_diagnostics::{Diagnostic, DiagnosticKind, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_semantic::{AnyImport, Binding, Imported, NodeId, ResolvedReferenceId, Scope}; -use ruff_text_size::{Ranged, TextRange}; +use ruff_python_semantic::{Binding, Imported, NodeId, Scope}; +use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::codes::Rule; use crate::fix; use crate::importer::ImportedMembers; +use crate::rules::flake8_type_checking::helpers::{is_typing_reference, quote_annotation}; +use crate::rules::flake8_type_checking::imports::ImportBinding; use crate::rules::isort::{categorize, ImportSection, ImportType}; /// ## What it does @@ -24,6 +27,10 @@ use crate::rules::isort::{categorize, ImportSection, ImportType}; /// instead be imported conditionally under an `if TYPE_CHECKING:` block to /// minimize runtime overhead. /// +/// If [`flake8-type-checking.quote-annotations`] is set to `true`, +/// annotations will be wrapped in quotes if doing so would enable the +/// corresponding import to be moved into an `if TYPE_CHECKING:` block. +/// /// If a class _requires_ that type annotations be available at runtime (as is /// the case for Pydantic, SQLAlchemy, and other libraries), consider using /// the [`flake8-type-checking.runtime-evaluated-base-classes`] and @@ -56,6 +63,7 @@ use crate::rules::isort::{categorize, ImportSection, ImportType}; /// ``` /// /// ## Options +/// - `flake8-type-checking.quote-annotations` /// - `flake8-type-checking.runtime-evaluated-base-classes` /// - `flake8-type-checking.runtime-evaluated-decorators` /// @@ -92,6 +100,10 @@ impl Violation for TypingOnlyFirstPartyImport { /// instead be imported conditionally under an `if TYPE_CHECKING:` block to /// minimize runtime overhead. /// +/// If [`flake8-type-checking.quote-annotations`] is set to `true`, +/// annotations will be wrapped in quotes if doing so would enable the +/// corresponding import to be moved into an `if TYPE_CHECKING:` block. +/// /// If a class _requires_ that type annotations be available at runtime (as is /// the case for Pydantic, SQLAlchemy, and other libraries), consider using /// the [`flake8-type-checking.runtime-evaluated-base-classes`] and @@ -124,6 +136,7 @@ impl Violation for TypingOnlyFirstPartyImport { /// ``` /// /// ## Options +/// - `flake8-type-checking.quote-annotations` /// - `flake8-type-checking.runtime-evaluated-base-classes` /// - `flake8-type-checking.runtime-evaluated-decorators` /// @@ -160,6 +173,10 @@ impl Violation for TypingOnlyThirdPartyImport { /// instead be imported conditionally under an `if TYPE_CHECKING:` block to /// minimize runtime overhead. /// +/// If [`flake8-type-checking.quote-annotations`] is set to `true`, +/// annotations will be wrapped in quotes if doing so would enable the +/// corresponding import to be moved into an `if TYPE_CHECKING:` block. +/// /// If a class _requires_ that type annotations be available at runtime (as is /// the case for Pydantic, SQLAlchemy, and other libraries), consider using /// the [`flake8-type-checking.runtime-evaluated-base-classes`] and @@ -192,6 +209,7 @@ impl Violation for TypingOnlyThirdPartyImport { /// ``` /// /// ## Options +/// - `flake8-type-checking.quote-annotations` /// - `flake8-type-checking.runtime-evaluated-base-classes` /// - `flake8-type-checking.runtime-evaluated-decorators` /// @@ -253,13 +271,12 @@ pub(crate) fn typing_only_runtime_import( }; if binding.context.is_runtime() - && binding.references().all(|reference_id| { - checker - .semantic() - .reference(reference_id) - .context() - .is_typing() - }) + && binding + .references() + .map(|reference_id| checker.semantic().reference(reference_id)) + .all(|reference| { + is_typing_reference(reference, &checker.settings.flake8_type_checking) + }) { let qualified_name = import.qualified_name(); @@ -310,6 +327,7 @@ pub(crate) fn typing_only_runtime_import( let import = ImportBinding { import, reference_id, + binding, range: binding.range(), parent_range: binding.parent_range(checker.semantic()), }; @@ -376,24 +394,6 @@ pub(crate) fn typing_only_runtime_import( } } -/// A runtime-required import with its surrounding context. -struct ImportBinding<'a> { - /// The qualified name of the import (e.g., `typing.List` for `from typing import List`). - import: AnyImport<'a>, - /// The first reference to the imported symbol. - reference_id: ResolvedReferenceId, - /// The trimmed range of the import (e.g., `List` in `from typing import List`). - range: TextRange, - /// The range of the import's parent statement. - parent_range: Option, -} - -impl Ranged for ImportBinding<'_> { - fn range(&self) -> TextRange { - self.range - } -} - /// Return the [`Rule`] for the given import type. fn rule_for(import_type: ImportType) -> Rule { match import_type { @@ -482,9 +482,35 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> checker.source_type, )?; - Ok( - Fix::unsafe_edits(remove_import_edit, add_import_edit.into_edits()).isolate( - Checker::isolation(checker.semantic().parent_statement_id(node_id)), - ), + // Step 3) Quote any runtime usages of the referenced symbol. + let quote_reference_edits = imports + .iter() + .flat_map(|ImportBinding { binding, .. }| { + binding.references.iter().filter_map(|reference_id| { + let reference = checker.semantic().reference(*reference_id); + if reference.context().is_runtime() { + Some(quote_annotation( + reference.expression_id()?, + checker.semantic(), + checker.locator(), + checker.stylist(), + checker.generator(), + )) + } else { + None + } + }) + }) + .collect::>>()?; + + Ok(Fix::unsafe_edits( + remove_import_edit, + add_import_edit + .into_edits() + .into_iter() + .chain(quote_reference_edits.into_iter().unique()), ) + .isolate(Checker::isolation( + checker.semantic().parent_statement_id(node_id), + ))) } diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/settings.rs b/crates/ruff_linter/src/rules/flake8_type_checking/settings.rs index 425f02fe550a4..16baf1b91edbe 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/settings.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/settings.rs @@ -6,17 +6,19 @@ use ruff_macros::CacheKey; pub struct Settings { pub strict: bool, pub exempt_modules: Vec, - pub runtime_evaluated_base_classes: Vec, - pub runtime_evaluated_decorators: Vec, + pub runtime_required_base_classes: Vec, + pub runtime_required_decorators: Vec, + pub quote_annotations: bool, } impl Default for Settings { fn default() -> Self { Self { strict: false, - exempt_modules: vec!["typing".to_string()], - runtime_evaluated_base_classes: vec![], - runtime_evaluated_decorators: vec![], + exempt_modules: vec!["typing".to_string(), "typing_extensions".to_string()], + runtime_required_base_classes: vec![], + runtime_required_decorators: vec![], + quote_annotations: false, } } } diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__quote_runtime-import-in-type-checking-block_quote.py.snap b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__quote_runtime-import-in-type-checking-block_quote.py.snap new file mode 100644 index 0000000000000..ae71c56c8195a --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__quote_runtime-import-in-type-checking-block_quote.py.snap @@ -0,0 +1,24 @@ +--- +source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +--- +quote.py:64:28: TCH004 [*] Quote references to `pandas.DataFrame`. Import is in a type-checking block. + | +63 | if TYPE_CHECKING: +64 | from pandas import DataFrame + | ^^^^^^^^^ TCH004 +65 | +66 | def func(value: DataFrame): + | + = help: Quote references + +ℹ Unsafe fix +63 63 | if TYPE_CHECKING: +64 64 | from pandas import DataFrame +65 65 | +66 |- def func(value: DataFrame): + 66 |+ def func(value: "DataFrame"): +67 67 | ... +68 68 | +69 69 | + + diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__quote_typing-only-third-party-import_quote.py.snap b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__quote_typing-only-third-party-import_quote.py.snap new file mode 100644 index 0000000000000..3a4417a661d87 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__quote_typing-only-third-party-import_quote.py.snap @@ -0,0 +1,333 @@ +--- +source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +--- +quote.py:2:24: TCH002 [*] Move third-party import `pandas.DataFrame` into a type-checking block + | +1 | def f(): +2 | from pandas import DataFrame + | ^^^^^^^^^ TCH002 +3 | +4 | def baz() -> DataFrame: + | + = help: Move into type-checking block + +ℹ Unsafe fix +1 |-def f(): + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: +2 4 | from pandas import DataFrame + 5 |+def f(): +3 6 | +4 |- def baz() -> DataFrame: + 7 |+ def baz() -> "DataFrame": +5 8 | ... +6 9 | +7 10 | + +quote.py:9:24: TCH002 [*] Move third-party import `pandas.DataFrame` into a type-checking block + | + 8 | def f(): + 9 | from pandas import DataFrame + | ^^^^^^^^^ TCH002 +10 | +11 | def baz() -> DataFrame[int]: + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ from pandas import DataFrame +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +6 10 | +7 11 | +8 12 | def f(): +9 |- from pandas import DataFrame +10 13 | +11 |- def baz() -> DataFrame[int]: + 14 |+ def baz() -> "DataFrame[int]": +12 15 | ... +13 16 | +14 17 | + +quote.py:16:24: TCH002 Move third-party import `pandas.DataFrame` into a type-checking block + | +15 | def f(): +16 | from pandas import DataFrame + | ^^^^^^^^^ TCH002 +17 | +18 | def baz() -> DataFrame["int"]: + | + = help: Move into type-checking block + +quote.py:23:22: TCH002 [*] Move third-party import `pandas` into a type-checking block + | +22 | def f(): +23 | import pandas as pd + | ^^ TCH002 +24 | +25 | def baz() -> pd.DataFrame: + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ import pandas as pd +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +20 24 | +21 25 | +22 26 | def f(): +23 |- import pandas as pd +24 27 | +25 |- def baz() -> pd.DataFrame: + 28 |+ def baz() -> "pd.DataFrame": +26 29 | ... +27 30 | +28 31 | + +quote.py:30:22: TCH002 [*] Move third-party import `pandas` into a type-checking block + | +29 | def f(): +30 | import pandas as pd + | ^^ TCH002 +31 | +32 | def baz() -> pd.DataFrame.Extra: + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ import pandas as pd +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +27 31 | +28 32 | +29 33 | def f(): +30 |- import pandas as pd +31 34 | +32 |- def baz() -> pd.DataFrame.Extra: + 35 |+ def baz() -> "pd.DataFrame.Extra": +33 36 | ... +34 37 | +35 38 | + +quote.py:37:22: TCH002 [*] Move third-party import `pandas` into a type-checking block + | +36 | def f(): +37 | import pandas as pd + | ^^ TCH002 +38 | +39 | def baz() -> pd.DataFrame | int: + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ import pandas as pd +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +34 38 | +35 39 | +36 40 | def f(): +37 |- import pandas as pd +38 41 | +39 |- def baz() -> pd.DataFrame | int: + 42 |+ def baz() -> "pd.DataFrame | int": +40 43 | ... +41 44 | +42 45 | + +quote.py:45:24: TCH002 [*] Move third-party import `pandas.DataFrame` into a type-checking block + | +44 | def f(): +45 | from pandas import DataFrame + | ^^^^^^^^^ TCH002 +46 | +47 | def baz() -> DataFrame(): + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ from pandas import DataFrame +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +42 46 | +43 47 | +44 48 | def f(): +45 |- from pandas import DataFrame +46 49 | +47 |- def baz() -> DataFrame(): + 50 |+ def baz() -> "DataFrame()": +48 51 | ... +49 52 | +50 53 | + +quote.py:54:24: TCH002 Move third-party import `pandas.DataFrame` into a type-checking block + | +52 | from typing import Literal +53 | +54 | from pandas import DataFrame + | ^^^^^^^^^ TCH002 +55 | +56 | def baz() -> DataFrame[Literal["int"]]: + | + = help: Move into type-checking block + +quote.py:71:24: TCH002 [*] Move third-party import `pandas.DataFrame` into a type-checking block + | +70 | def f(): +71 | from pandas import DataFrame, Series + | ^^^^^^^^^ TCH002 +72 | +73 | def baz() -> DataFrame | Series: + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ from pandas import DataFrame, Series +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +68 72 | +69 73 | +70 74 | def f(): +71 |- from pandas import DataFrame, Series +72 75 | +73 |- def baz() -> DataFrame | Series: + 76 |+ def baz() -> "DataFrame | Series": +74 77 | ... +75 78 | +76 79 | + +quote.py:71:35: TCH002 [*] Move third-party import `pandas.Series` into a type-checking block + | +70 | def f(): +71 | from pandas import DataFrame, Series + | ^^^^^^ TCH002 +72 | +73 | def baz() -> DataFrame | Series: + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ from pandas import DataFrame, Series +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +68 72 | +69 73 | +70 74 | def f(): +71 |- from pandas import DataFrame, Series +72 75 | +73 |- def baz() -> DataFrame | Series: + 76 |+ def baz() -> "DataFrame | Series": +74 77 | ... +75 78 | +76 79 | + +quote.py:78:24: TCH002 [*] Move third-party import `pandas.DataFrame` into a type-checking block + | +77 | def f(): +78 | from pandas import DataFrame, Series + | ^^^^^^^^^ TCH002 +79 | +80 | def baz() -> ( + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ from pandas import DataFrame, Series +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +75 79 | +76 80 | +77 81 | def f(): +78 |- from pandas import DataFrame, Series +79 82 | +80 83 | def baz() -> ( +81 |- DataFrame | +82 |- Series + 84 |+ "DataFrame | Series" +83 85 | ): +84 86 | ... +85 87 | +86 88 | class C: +87 |- x: DataFrame[ +88 |- int +89 |- ] = 1 + 89 |+ x: "DataFrame[int]" = 1 + +quote.py:78:35: TCH002 [*] Move third-party import `pandas.Series` into a type-checking block + | +77 | def f(): +78 | from pandas import DataFrame, Series + | ^^^^^^ TCH002 +79 | +80 | def baz() -> ( + | + = help: Move into type-checking block + +ℹ Unsafe fix + 1 |+from typing import TYPE_CHECKING + 2 |+ + 3 |+if TYPE_CHECKING: + 4 |+ from pandas import DataFrame, Series +1 5 | def f(): +2 6 | from pandas import DataFrame +3 7 | +-------------------------------------------------------------------------------- +75 79 | +76 80 | +77 81 | def f(): +78 |- from pandas import DataFrame, Series +79 82 | +80 83 | def baz() -> ( +81 |- DataFrame | +82 |- Series + 84 |+ "DataFrame | Series" +83 85 | ): +84 86 | ... +85 87 | +86 88 | class C: +87 |- x: DataFrame[ +88 |- int +89 |- ] = 1 + 89 |+ x: "DataFrame[int]" = 1 + + diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_quote.py.snap b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_quote.py.snap new file mode 100644 index 0000000000000..c09777853b97a --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_quote.py.snap @@ -0,0 +1,29 @@ +--- +source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +--- +quote.py:64:28: TCH004 [*] Move import `pandas.DataFrame` out of type-checking block. Import is used for more than type hinting. + | +63 | if TYPE_CHECKING: +64 | from pandas import DataFrame + | ^^^^^^^^^ TCH004 +65 | +66 | def func(value: DataFrame): + | + = help: Move out of type-checking block + +ℹ Unsafe fix + 1 |+from pandas import DataFrame +1 2 | def f(): +2 3 | from pandas import DataFrame +3 4 | +-------------------------------------------------------------------------------- +61 62 | from typing import TYPE_CHECKING +62 63 | +63 64 | if TYPE_CHECKING: +64 |- from pandas import DataFrame + 65 |+ pass +65 66 | +66 67 | def func(value: DataFrame): +67 68 | ... + + diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__typing-only-third-party-import_quote.py.snap b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__typing-only-third-party-import_quote.py.snap new file mode 100644 index 0000000000000..6c5ead27428ce --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__typing-only-third-party-import_quote.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__typing-only-third-party-import_singledispatch.py.snap b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__typing-only-third-party-import_singledispatch.py.snap new file mode 100644 index 0000000000000..5b646c6b34011 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__typing-only-third-party-import_singledispatch.py.snap @@ -0,0 +1,27 @@ +--- +source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +--- +singledispatch.py:10:20: TCH002 [*] Move third-party import `pandas.DataFrame` into a type-checking block + | + 8 | from numpy.typing import ArrayLike + 9 | from scipy.sparse import spmatrix +10 | from pandas import DataFrame + | ^^^^^^^^^ TCH002 +11 | +12 | if TYPE_CHECKING: + | + = help: Move into type-checking block + +ℹ Unsafe fix +7 7 | from numpy import asarray +8 8 | from numpy.typing import ArrayLike +9 9 | from scipy.sparse import spmatrix +10 |-from pandas import DataFrame +11 10 | +12 11 | if TYPE_CHECKING: + 12 |+ from pandas import DataFrame +13 13 | from numpy import ndarray +14 14 | +15 15 | + + diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs index 0fc1cbee681de..dc598dbb9f8ff 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs @@ -65,11 +65,11 @@ pub(crate) fn path_constructor_current_directory(checker: &mut Checker, expr: &E return; } - let [Expr::StringLiteral(ast::ExprStringLiteral { value, range, .. })] = args.as_slice() else { + let [Expr::StringLiteral(ast::ExprStringLiteral { value, range })] = args.as_slice() else { return; }; - if matches!(value.as_str(), "" | ".") { + if matches!(value.to_str(), "" | ".") { let mut diagnostic = Diagnostic::new(PathConstructorCurrentDirectory, *range); diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(*range))); checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs index 7e18f8290ed4f..55600d45aceb9 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs @@ -705,8 +705,6 @@ impl Violation for OsReadlink { /// ## Examples /// ```python /// import os -/// -/// import os /// from pwd import getpwuid /// from grp import getgrgid /// @@ -719,8 +717,6 @@ impl Violation for OsReadlink { /// ```python /// from pathlib import Path /// -/// from pathlib import Path -/// /// file_path = Path(file_name) /// stat = file_path.stat() /// owner_name = file_path.owner() diff --git a/crates/ruff_linter/src/rules/flynt/helpers.rs b/crates/ruff_linter/src/rules/flynt/helpers.rs index 1caa107c40919..7a6af204d13f9 100644 --- a/crates/ruff_linter/src/rules/flynt/helpers.rs +++ b/crates/ruff_linter/src/rules/flynt/helpers.rs @@ -1,25 +1,23 @@ use ruff_python_ast::{self as ast, Arguments, ConversionFlag, Expr}; use ruff_text_size::TextRange; -/// Wrap an expression in a `FormattedValue` with no special formatting. -fn to_formatted_value_expr(inner: &Expr) -> Expr { - let node = ast::ExprFormattedValue { - value: Box::new(inner.clone()), +/// Wrap an expression in a [`ast::FStringElement::Expression`] with no special formatting. +fn to_f_string_expression_element(inner: &Expr) -> ast::FStringElement { + ast::FStringElement::Expression(ast::FStringExpressionElement { + expression: Box::new(inner.clone()), debug_text: None, conversion: ConversionFlag::None, format_spec: None, range: TextRange::default(), - }; - node.into() + }) } -/// Convert a string to a constant string expression. -pub(super) fn to_constant_string(s: &str) -> Expr { - let node = ast::ExprStringLiteral { +/// Convert a string to a [`ast::FStringElement::Literal`]. +pub(super) fn to_f_string_literal_element(s: &str) -> ast::FStringElement { + ast::FStringElement::Literal(ast::FStringLiteralElement { value: s.to_owned(), - ..ast::ExprStringLiteral::default() - }; - node.into() + range: TextRange::default(), + }) } /// Figure out if `expr` represents a "simple" call @@ -51,15 +49,19 @@ fn is_simple_callee(func: &Expr) -> bool { } /// Convert an expression to a f-string element (if it looks like a good idea). -pub(super) fn to_f_string_element(expr: &Expr) -> Option { +pub(super) fn to_f_string_element(expr: &Expr) -> Option { match expr { - // These are directly handled by `unparse_f_string_element`: - Expr::StringLiteral(_) | Expr::FString(_) | Expr::FormattedValue(_) => Some(expr.clone()), + Expr::StringLiteral(ast::ExprStringLiteral { value, range }) => { + Some(ast::FStringElement::Literal(ast::FStringLiteralElement { + value: value.to_string(), + range: *range, + })) + } // These should be pretty safe to wrap in a formatted value. Expr::NumberLiteral(_) | Expr::BooleanLiteral(_) | Expr::Name(_) | Expr::Attribute(_) => { - Some(to_formatted_value_expr(expr)) + Some(to_f_string_expression_element(expr)) } - Expr::Call(_) if is_simple_call(expr) => Some(to_formatted_value_expr(expr)), + Expr::Call(_) if is_simple_call(expr) => Some(to_f_string_expression_element(expr)), _ => None, } } diff --git a/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs b/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs index 8da7a91eb2c49..86c77bbb0ed73 100644 --- a/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs +++ b/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs @@ -62,25 +62,23 @@ fn is_static_length(elts: &[Expr]) -> bool { fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { // If all elements are string constants, join them into a single string. if joinees.iter().all(Expr::is_string_literal_expr) { - let node = ast::ExprStringLiteral { + let node = ast::StringLiteral { value: joinees .iter() .filter_map(|expr| { if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = expr { - Some(value.as_str()) + Some(value.to_str()) } else { None } }) .join(joiner), - unicode: false, - implicit_concatenated: false, - range: TextRange::default(), + ..ast::StringLiteral::default() }; return Some(node.into()); } - let mut fstring_elems = Vec::with_capacity(joinees.len() * 2); + let mut f_string_elements = Vec::with_capacity(joinees.len() * 2); let mut first = true; for expr in joinees { @@ -90,14 +88,13 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { return None; } if !std::mem::take(&mut first) { - fstring_elems.push(helpers::to_constant_string(joiner)); + f_string_elements.push(helpers::to_f_string_literal_element(joiner)); } - fstring_elems.push(helpers::to_f_string_element(expr)?); + f_string_elements.push(helpers::to_f_string_element(expr)?); } - let node = ast::ExprFString { - values: fstring_elems, - implicit_concatenated: false, + let node = ast::FString { + elements: f_string_elements, range: TextRange::default(), }; Some(node.into()) @@ -130,7 +127,7 @@ pub(crate) fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: }; // Try to build the fstring (internally checks whether e.g. the elements are - // convertible to f-string parts). + // convertible to f-string elements). let Some(new_expr) = build_fstring(joiner, joinees) else { return; }; diff --git a/crates/ruff_linter/src/rules/isort/block.rs b/crates/ruff_linter/src/rules/isort/block.rs index 4f24a1c1d2c88..8389fa86a2732 100644 --- a/crates/ruff_linter/src/rules/isort/block.rs +++ b/crates/ruff_linter/src/rules/isort/block.rs @@ -1,7 +1,7 @@ use std::iter::Peekable; use std::slice; -use ruff_notebook::Notebook; +use ruff_notebook::CellOffsets; use ruff_python_ast::statement_visitor::StatementVisitor; use ruff_python_ast::{self as ast, ElifElseClause, ExceptHandler, MatchCase, Stmt}; use ruff_source_file::Locator; @@ -9,7 +9,6 @@ use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::directives::IsortDirectives; use crate::rules::isort::helpers; -use crate::source_kind::SourceKind; /// A block of imports within a Python module. #[derive(Debug, Default)] @@ -43,7 +42,7 @@ impl<'a> BlockBuilder<'a> { locator: &'a Locator<'a>, directives: &'a IsortDirectives, is_stub: bool, - source_kind: &'a SourceKind, + cell_offsets: Option<&'a CellOffsets>, ) -> Self { Self { locator, @@ -52,10 +51,7 @@ impl<'a> BlockBuilder<'a> { splits: directives.splits.iter().peekable(), exclusions: &directives.exclusions, nested: false, - cell_offsets: source_kind - .as_ipy_notebook() - .map(Notebook::cell_offsets) - .map(|offsets| offsets.iter().peekable()), + cell_offsets: cell_offsets.map(|offsets| offsets.iter().peekable()), } } diff --git a/crates/ruff_linter/src/rules/isort/categorize.rs b/crates/ruff_linter/src/rules/isort/categorize.rs index 6c086bfb2f7e2..8ab090645ab62 100644 --- a/crates/ruff_linter/src/rules/isort/categorize.rs +++ b/crates/ruff_linter/src/rules/isort/categorize.rs @@ -106,6 +106,11 @@ pub(crate) fn categorize<'a>( &ImportSection::Known(ImportType::FirstParty), Reason::SourceMatch(src), ) + } else if matches!(level, None | Some(0)) && module_name == "__main__" { + ( + &ImportSection::Known(ImportType::FirstParty), + Reason::KnownFirstParty, + ) } else { ( &ImportSection::Known(ImportType::ThirdParty), diff --git a/crates/ruff_linter/src/rules/isort/mod.rs b/crates/ruff_linter/src/rules/isort/mod.rs index 73380ca4eefd0..d77a818aa8fff 100644 --- a/crates/ruff_linter/src/rules/isort/mod.rs +++ b/crates/ruff_linter/src/rules/isort/mod.rs @@ -145,6 +145,15 @@ fn format_import_block( target_version: PythonVersion, settings: &Settings, ) -> String { + #[derive(Debug, Copy, Clone, PartialEq, Eq)] + enum LineInsertion { + /// A blank line should be inserted as soon as the next import is + /// of a different type (i.e., direct vs. `from`). + Necessary, + /// A blank line has already been inserted. + Inserted, + } + // Categorize by type (e.g., first-party vs. third-party). let mut block_by_type = categorize_imports( block, @@ -171,7 +180,7 @@ fn format_import_block( continue; }; - let imports = order_imports(import_block, settings); + let imports = order_imports(import_block, import_section, settings); // Add a blank line between every section. if is_first_block { @@ -182,13 +191,25 @@ fn format_import_block( pending_lines_before = false; } - let mut lines_inserted = false; - let mut has_direct_import = false; + let mut line_insertion = None; let mut is_first_statement = true; let lines_between_types = settings.lines_between_types; for import in imports { match import { Import((alias, comments)) => { + // Add a blank lines between direct and from imports. + if settings.from_first + && lines_between_types > 0 + && !settings.force_sort_within_sections + && line_insertion == Some(LineInsertion::Necessary) + { + for _ in 0..lines_between_types { + output.push_str(&stylist.line_ending()); + } + + line_insertion = Some(LineInsertion::Inserted); + } + output.push_str(&format::format_import( &alias, &comments, @@ -196,17 +217,23 @@ fn format_import_block( stylist, )); - has_direct_import = true; + if !settings.from_first { + line_insertion = Some(LineInsertion::Necessary); + } } ImportFrom((import_from, comments, trailing_comma, aliases)) => { - // Add a blank lines between direct and from imports - if lines_between_types > 0 && has_direct_import && !lines_inserted { + // Add a blank lines between direct and from imports. + if !settings.from_first + && lines_between_types > 0 + && !settings.force_sort_within_sections + && line_insertion == Some(LineInsertion::Necessary) + { for _ in 0..lines_between_types { output.push_str(&stylist.line_ending()); } - lines_inserted = true; + line_insertion = Some(LineInsertion::Inserted); } output.push_str(&format::format_import_from( @@ -221,6 +248,10 @@ fn format_import_block( settings.split_on_trailing_comma && matches!(trailing_comma, TrailingComma::Present), )); + + if settings.from_first { + line_insertion = Some(LineInsertion::Necessary); + } } } is_first_statement = false; @@ -262,6 +293,7 @@ mod tests { #[test_case(Path::new("force_sort_within_sections.py"))] #[test_case(Path::new("force_to_top.py"))] #[test_case(Path::new("force_wrap_aliases.py"))] + #[test_case(Path::new("future_from.py"))] #[test_case(Path::new("if_elif_else.py"))] #[test_case(Path::new("import_from_after_import.py"))] #[test_case(Path::new("inline_comments.py"))] @@ -672,6 +704,7 @@ mod tests { #[test_case(Path::new("force_sort_within_sections.py"))] #[test_case(Path::new("force_sort_within_sections_with_as_names.py"))] + #[test_case(Path::new("force_sort_within_sections_future.py"))] fn force_sort_within_sections(path: &Path) -> Result<()> { let snapshot = format!("force_sort_within_sections_{}", path.to_string_lossy()); let mut diagnostics = test_path( @@ -691,6 +724,26 @@ mod tests { Ok(()) } + #[test_case(Path::new("force_sort_within_sections_lines_between.py"))] + fn force_sort_within_sections_lines_between(path: &Path) -> Result<()> { + let snapshot = format!("force_sort_within_sections_{}", path.to_string_lossy()); + let mut diagnostics = test_path( + Path::new("isort").join(path).as_path(), + &LinterSettings { + isort: super::settings::Settings { + force_sort_within_sections: true, + lines_between_types: 2, + ..super::settings::Settings::default() + }, + src: vec![test_resource_path("fixtures/isort")], + ..LinterSettings::for_rule(Rule::UnsortedImports) + }, + )?; + diagnostics.sort_by_key(Ranged::start); + assert_messages!(snapshot, diagnostics); + Ok(()) + } + #[test_case(Path::new("comment.py"))] #[test_case(Path::new("comments_and_newlines.py"))] #[test_case(Path::new("docstring.py"))] @@ -819,6 +872,25 @@ mod tests { Ok(()) } + #[test_case(Path::new("from_first.py"))] + fn from_first(path: &Path) -> Result<()> { + let snapshot = format!("from_first_{}", path.to_string_lossy()); + let diagnostics = test_path( + Path::new("isort").join(path).as_path(), + &LinterSettings { + isort: super::settings::Settings { + from_first: true, + lines_between_types: 1, + ..super::settings::Settings::default() + }, + src: vec![test_resource_path("fixtures/isort")], + ..LinterSettings::for_rule(Rule::UnsortedImports) + }, + )?; + assert_messages!(snapshot, diagnostics); + Ok(()) + } + #[test_case(Path::new("relative_imports_order.py"))] fn closest_to_furthest(path: &Path) -> Result<()> { let snapshot = format!("closest_to_furthest_{}", path.to_string_lossy()); @@ -1033,6 +1105,30 @@ mod tests { Ok(()) } + #[test_case(Path::new("main_first_party.py"))] + fn main_is_first_party(path: &Path) -> Result<()> { + let snapshot = format!("sections_{}", path.to_string_lossy()); + let diagnostics = test_path( + Path::new("isort").join(path).as_path(), + &LinterSettings { + src: vec![test_resource_path("fixtures/isort")], + isort: super::settings::Settings { + known_modules: KnownModules::new( + vec![pattern("first_party")], + vec![], + vec![], + vec![], + FxHashMap::default(), + ), + ..super::settings::Settings::default() + }, + ..LinterSettings::for_rule(Rule::UnsortedImports) + }, + )?; + assert_messages!(snapshot, diagnostics); + Ok(()) + } + #[test] fn detect_same_package() -> Result<()> { let diagnostics = test_path( @@ -1066,4 +1162,47 @@ mod tests { assert_messages!(diagnostics); Ok(()) } + + #[test_case(Path::new("length_sort_straight_imports.py"))] + #[test_case(Path::new("length_sort_from_imports.py"))] + #[test_case(Path::new("length_sort_straight_and_from_imports.py"))] + #[test_case(Path::new("length_sort_non_ascii_members.py"))] + #[test_case(Path::new("length_sort_non_ascii_modules.py"))] + #[test_case(Path::new("length_sort_with_relative_imports.py"))] + fn length_sort(path: &Path) -> Result<()> { + let snapshot = format!("length_sort__{}", path.to_string_lossy()); + let diagnostics = test_path( + Path::new("isort").join(path).as_path(), + &LinterSettings { + isort: super::settings::Settings { + length_sort: true, + ..super::settings::Settings::default() + }, + src: vec![test_resource_path("fixtures/isort")], + ..LinterSettings::for_rule(Rule::UnsortedImports) + }, + )?; + assert_messages!(snapshot, diagnostics); + Ok(()) + } + + #[test_case(Path::new("length_sort_straight_imports.py"))] + #[test_case(Path::new("length_sort_from_imports.py"))] + #[test_case(Path::new("length_sort_straight_and_from_imports.py"))] + fn length_sort_straight(path: &Path) -> Result<()> { + let snapshot = format!("length_sort_straight__{}", path.to_string_lossy()); + let diagnostics = test_path( + Path::new("isort").join(path).as_path(), + &LinterSettings { + isort: super::settings::Settings { + length_sort_straight: true, + ..super::settings::Settings::default() + }, + src: vec![test_resource_path("fixtures/isort")], + ..LinterSettings::for_rule(Rule::UnsortedImports) + }, + )?; + assert_messages!(snapshot, diagnostics); + Ok(()) + } } diff --git a/crates/ruff_linter/src/rules/isort/order.rs b/crates/ruff_linter/src/rules/isort/order.rs index 06002fd3ebb9b..7f1f6f97fccb3 100644 --- a/crates/ruff_linter/src/rules/isort/order.rs +++ b/crates/ruff_linter/src/rules/isort/order.rs @@ -1,3 +1,5 @@ +use crate::rules::isort::sorting::ImportStyle; +use crate::rules::isort::{ImportSection, ImportType}; use itertools::Itertools; use super::settings::Settings; @@ -7,6 +9,7 @@ use super::types::{AliasData, CommentSet, ImportBlock, ImportFromStatement}; pub(crate) fn order_imports<'a>( block: ImportBlock<'a>, + section: &ImportSection, settings: &Settings, ) -> Vec> { let straight_imports = block.import.into_iter(); @@ -51,26 +54,67 @@ pub(crate) fn order_imports<'a>( }, ); - let ordered_imports = if settings.force_sort_within_sections { + let ordered_imports = if matches!(section, ImportSection::Known(ImportType::Future)) { + from_imports + .sorted_by_cached_key(|(import_from, _, _, aliases)| { + ModuleKey::from_module( + import_from.module, + None, + import_from.level, + aliases.first().map(|(alias, _)| (alias.name, alias.asname)), + ImportStyle::From, + settings, + ) + }) + .map(ImportFrom) + .chain( + straight_imports + .sorted_by_cached_key(|(alias, _)| { + ModuleKey::from_module( + Some(alias.name), + alias.asname, + None, + None, + ImportStyle::Straight, + settings, + ) + }) + .map(Import), + ) + .collect() + } else if settings.force_sort_within_sections { straight_imports .map(Import) .chain(from_imports.map(ImportFrom)) .sorted_by_cached_key(|import| match import { - Import((alias, _)) => { - ModuleKey::from_module(Some(alias.name), alias.asname, None, None, settings) - } + Import((alias, _)) => ModuleKey::from_module( + Some(alias.name), + alias.asname, + None, + None, + ImportStyle::Straight, + settings, + ), ImportFrom((import_from, _, _, aliases)) => ModuleKey::from_module( import_from.module, None, import_from.level, aliases.first().map(|(alias, _)| (alias.name, alias.asname)), + ImportStyle::From, settings, ), }) .collect() } else { let ordered_straight_imports = straight_imports.sorted_by_cached_key(|(alias, _)| { - ModuleKey::from_module(Some(alias.name), alias.asname, None, None, settings) + ModuleKey::from_module( + Some(alias.name), + alias.asname, + None, + None, + ImportStyle::Straight, + settings, + ) }); let ordered_from_imports = from_imports.sorted_by_cached_key(|(import_from, _, _, aliases)| { @@ -79,14 +123,23 @@ pub(crate) fn order_imports<'a>( None, import_from.level, aliases.first().map(|(alias, _)| (alias.name, alias.asname)), + ImportStyle::From, settings, ) }); - ordered_straight_imports - .into_iter() - .map(Import) - .chain(ordered_from_imports.into_iter().map(ImportFrom)) - .collect() + if settings.from_first { + ordered_from_imports + .into_iter() + .map(ImportFrom) + .chain(ordered_straight_imports.into_iter().map(Import)) + .collect() + } else { + ordered_straight_imports + .into_iter() + .map(Import) + .chain(ordered_from_imports.into_iter().map(ImportFrom)) + .collect() + } }; ordered_imports diff --git a/crates/ruff_linter/src/rules/isort/settings.rs b/crates/ruff_linter/src/rules/isort/settings.rs index 6e27a2debf4ee..2a28a3c8b396b 100644 --- a/crates/ruff_linter/src/rules/isort/settings.rs +++ b/crates/ruff_linter/src/rules/isort/settings.rs @@ -57,6 +57,9 @@ pub struct Settings { pub forced_separate: Vec, pub section_order: Vec, pub no_sections: bool, + pub from_first: bool, + pub length_sort: bool, + pub length_sort_straight: bool, } impl Default for Settings { @@ -84,6 +87,9 @@ impl Default for Settings { forced_separate: Vec::new(), section_order: ImportType::iter().map(ImportSection::Known).collect(), no_sections: false, + from_first: false, + length_sort: false, + length_sort_straight: false, } } } diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__force_sort_within_sections_force_sort_within_sections_future.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__force_sort_within_sections_force_sort_within_sections_future.py.snap new file mode 100644 index 0000000000000..6864d488b75ed --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__force_sort_within_sections_force_sort_within_sections_future.py.snap @@ -0,0 +1,16 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +force_sort_within_sections_future.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / import __future__ +2 | | from __future__ import annotations + | + = help: Organize imports + +ℹ Safe fix + 1 |+from __future__ import annotations +1 2 | import __future__ +2 |-from __future__ import annotations + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__force_sort_within_sections_force_sort_within_sections_lines_between.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__force_sort_within_sections_force_sort_within_sections_lines_between.py.snap new file mode 100644 index 0000000000000..ed369f0fd61f0 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__force_sort_within_sections_force_sort_within_sections_lines_between.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__from_first_from_first.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__from_first_from_first.py.snap new file mode 100644 index 0000000000000..ed369f0fd61f0 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__from_first_from_first.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__future_from.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__future_from.py.snap new file mode 100644 index 0000000000000..f3f5cd2a3574d --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__future_from.py.snap @@ -0,0 +1,16 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +future_from.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / import __future__ +2 | | from __future__ import annotations + | + = help: Organize imports + +ℹ Safe fix + 1 |+from __future__ import annotations +1 2 | import __future__ +2 |-from __future__ import annotations + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_from_imports.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_from_imports.py.snap new file mode 100644 index 0000000000000..a2183e7de32c7 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_from_imports.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_from_imports.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / from mediuuuuuuuuuuum import a +2 | | from short import b +3 | | from loooooooooooooooooooooog import c + | + = help: Organize imports + +ℹ Safe fix + 1 |+from short import b +1 2 | from mediuuuuuuuuuuum import a +2 |-from short import b +3 3 | from loooooooooooooooooooooog import c + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_non_ascii_members.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_non_ascii_members.py.snap new file mode 100644 index 0000000000000..d6cfc0e340920 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_non_ascii_members.py.snap @@ -0,0 +1,37 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_non_ascii_members.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | + 1 | / from module1 import ( + 2 | | loooooooooooooong, + 3 | | σηορτ, + 4 | | mediuuuuum, + 5 | | shoort, + 6 | | looooooooooooooong, + 7 | | μεδιυυυυυμ, + 8 | | short, + 9 | | mediuuuuuum, +10 | | λοοοοοοοοοοοοοονγ, +11 | | ) + | + = help: Organize imports + +ℹ Safe fix +1 1 | from module1 import ( +2 |- loooooooooooooong, + 2 |+ short, +3 3 | σηορτ, + 4 |+ shoort, +4 5 | mediuuuuum, +5 |- shoort, +6 |- looooooooooooooong, +7 6 | μεδιυυυυυμ, +8 |- short, +9 7 | mediuuuuuum, + 8 |+ loooooooooooooong, +10 9 | λοοοοοοοοοοοοοονγ, + 10 |+ looooooooooooooong, +11 11 | ) + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_non_ascii_modules.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_non_ascii_modules.py.snap new file mode 100644 index 0000000000000..e1d66bd9a7bb9 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_non_ascii_modules.py.snap @@ -0,0 +1,32 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_non_ascii_modules.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / import loooooooooooooong +2 | | import mediuuuuuum +3 | | import short +4 | | import σηορτ +5 | | import shoort +6 | | import mediuuuuum +7 | | import λοοοοοοοοοοοοοονγ +8 | | import μεδιυυυυυμ +9 | | import looooooooooooooong + | + = help: Organize imports + +ℹ Safe fix +1 |-import loooooooooooooong +2 |-import mediuuuuuum +3 1 | import short +4 2 | import σηορτ +5 3 | import shoort +6 4 | import mediuuuuum + 5 |+import μεδιυυυυυμ + 6 |+import mediuuuuuum + 7 |+import loooooooooooooong +7 8 | import λοοοοοοοοοοοοοονγ +8 |-import μεδιυυυυυμ +9 9 | import looooooooooooooong + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_straight_and_from_imports.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_straight_and_from_imports.py.snap new file mode 100644 index 0000000000000..7acc627804180 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_straight_and_from_imports.py.snap @@ -0,0 +1,26 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_straight_and_from_imports.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / import mediuuuuuum +2 | | import short +3 | | import looooooooooooooooong +4 | | from looooooooooooooong import a +5 | | from mediuuuum import c +6 | | from short import b + | + = help: Organize imports + +ℹ Safe fix + 1 |+import short +1 2 | import mediuuuuuum +2 |-import short +3 3 | import looooooooooooooooong +4 |-from looooooooooooooong import a + 4 |+from short import b +5 5 | from mediuuuum import c +6 |-from short import b + 6 |+from looooooooooooooong import a + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_straight_imports.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_straight_imports.py.snap new file mode 100644 index 0000000000000..6c73af3a2a8fa --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_straight_imports.py.snap @@ -0,0 +1,21 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_straight_imports.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / import mediuuuuuumb +2 | | import short +3 | | import looooooooooooooooong +4 | | import mediuuuuuuma + | + = help: Organize imports + +ℹ Safe fix + 1 |+import short + 2 |+import mediuuuuuuma +1 3 | import mediuuuuuumb +2 |-import short +3 4 | import looooooooooooooooong +4 |-import mediuuuuuuma + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_with_relative_imports.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_with_relative_imports.py.snap new file mode 100644 index 0000000000000..20531ecd26d43 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort__length_sort_with_relative_imports.py.snap @@ -0,0 +1,28 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_with_relative_imports.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / from ..looooooooooooooong import a +2 | | from ...mediuuuum import b +3 | | from .short import c +4 | | from ....short import c +5 | | from . import d +6 | | from .mediuuuum import a +7 | | from ......short import b + | + = help: Organize imports + +ℹ Safe fix +1 |-from ..looooooooooooooong import a +2 |-from ...mediuuuum import b + 1 |+from . import d +3 2 | from .short import c +4 3 | from ....short import c +5 |-from . import d +6 4 | from .mediuuuum import a +7 5 | from ......short import b + 6 |+from ...mediuuuum import b + 7 |+from ..looooooooooooooong import a + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_from_imports.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_from_imports.py.snap new file mode 100644 index 0000000000000..35bdec18f120c --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_from_imports.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_from_imports.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / from mediuuuuuuuuuuum import a +2 | | from short import b +3 | | from loooooooooooooooooooooog import c + | + = help: Organize imports + +ℹ Safe fix + 1 |+from loooooooooooooooooooooog import c +1 2 | from mediuuuuuuuuuuum import a +2 3 | from short import b +3 |-from loooooooooooooooooooooog import c + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_straight_and_from_imports.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_straight_and_from_imports.py.snap new file mode 100644 index 0000000000000..3cd80a04effd9 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_straight_and_from_imports.py.snap @@ -0,0 +1,23 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_straight_and_from_imports.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / import mediuuuuuum +2 | | import short +3 | | import looooooooooooooooong +4 | | from looooooooooooooong import a +5 | | from mediuuuum import c +6 | | from short import b + | + = help: Organize imports + +ℹ Safe fix + 1 |+import short +1 2 | import mediuuuuuum +2 |-import short +3 3 | import looooooooooooooooong +4 4 | from looooooooooooooong import a +5 5 | from mediuuuum import c + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_straight_imports.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_straight_imports.py.snap new file mode 100644 index 0000000000000..6c73af3a2a8fa --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__length_sort_straight__length_sort_straight_imports.py.snap @@ -0,0 +1,21 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +length_sort_straight_imports.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | +1 | / import mediuuuuuumb +2 | | import short +3 | | import looooooooooooooooong +4 | | import mediuuuuuuma + | + = help: Organize imports + +ℹ Safe fix + 1 |+import short + 2 |+import mediuuuuuuma +1 3 | import mediuuuuuumb +2 |-import short +3 4 | import looooooooooooooooong +4 |-import mediuuuuuuma + + diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__sections_main_first_party.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__sections_main_first_party.py.snap new file mode 100644 index 0000000000000..404ad962cb670 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__sections_main_first_party.py.snap @@ -0,0 +1,31 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +main_first_party.py:1:1: I001 [*] Import block is un-sorted or un-formatted + | + 1 | / import os + 2 | | + 3 | | import __main__ + 4 | | import third_party + 5 | | + 6 | | import first_party + 7 | | + 8 | | os.a + | |_^ I001 + 9 | third_party.a +10 | __main__.a + | + = help: Organize imports + +ℹ Safe fix +1 1 | import os +2 2 | +3 |-import __main__ +4 3 | import third_party +5 4 | + 5 |+import __main__ +6 6 | import first_party +7 7 | +8 8 | os.a + + diff --git a/crates/ruff_linter/src/rules/isort/sorting.rs b/crates/ruff_linter/src/rules/isort/sorting.rs index cb6f01f730054..aa979fc90c89e 100644 --- a/crates/ruff_linter/src/rules/isort/sorting.rs +++ b/crates/ruff_linter/src/rules/isort/sorting.rs @@ -3,6 +3,7 @@ use std::{borrow::Cow, cmp::Ordering, cmp::Reverse}; use natord; +use unicode_width::UnicodeWidthStr; use ruff_python_stdlib::str; @@ -64,18 +65,27 @@ impl<'a> From for NatOrdStr<'a> { } } -#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)] pub(crate) enum Distance { Nearest(u32), Furthest(Reverse), } +#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)] +pub(crate) enum ImportStyle { + // Ex) `import foo` + Straight, + // Ex) `from foo import bar` + From, +} + /// A comparable key to capture the desired sorting order for an imported module (e.g., /// `foo` in `from foo import bar`). #[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pub(crate) struct ModuleKey<'a> { + force_to_top: bool, + maybe_length: Option, distance: Distance, - force_to_top: Option, maybe_lowercase_name: Option>, module_name: Option>, first_alias: Option>, @@ -88,26 +98,39 @@ impl<'a> ModuleKey<'a> { asname: Option<&'a str>, level: Option, first_alias: Option<(&'a str, Option<&'a str>)>, + style: ImportStyle, settings: &Settings, ) -> Self { + let level = level.unwrap_or_default(); + + let force_to_top = !name + .map(|name| settings.force_to_top.contains(name)) + .unwrap_or_default(); // `false` < `true` so we get forced to top first + + let maybe_length = (settings.length_sort + || (settings.length_sort_straight && style == ImportStyle::Straight)) + .then_some(name.map(str::width).unwrap_or_default() + level as usize); + let distance = match settings.relative_imports_order { - RelativeImportsOrder::ClosestToFurthest => Distance::Nearest(level.unwrap_or_default()), - RelativeImportsOrder::FurthestToClosest => { - Distance::Furthest(Reverse(level.unwrap_or_default())) - } + RelativeImportsOrder::ClosestToFurthest => Distance::Nearest(level), + RelativeImportsOrder::FurthestToClosest => Distance::Furthest(Reverse(level)), }; - let force_to_top = name.map(|name| !settings.force_to_top.contains(name)); // `false` < `true` so we get forced to top first + let maybe_lowercase_name = name.and_then(|name| { (!settings.case_sensitive).then_some(NatOrdStr(maybe_lowercase(name))) }); + let module_name = name.map(NatOrdStr::from); + let asname = asname.map(NatOrdStr::from); + let first_alias = first_alias.map(|(name, asname)| MemberKey::from_member(name, asname, settings)); Self { - distance, force_to_top, + maybe_length, + distance, maybe_lowercase_name, module_name, first_alias, @@ -122,6 +145,7 @@ impl<'a> ModuleKey<'a> { pub(crate) struct MemberKey<'a> { not_star_import: bool, member_type: Option, + maybe_length: Option, maybe_lowercase_name: Option>, module_name: NatOrdStr<'a>, asname: Option>, @@ -133,6 +157,7 @@ impl<'a> MemberKey<'a> { let member_type = settings .order_by_type .then_some(member_type(name, settings)); + let maybe_length = settings.length_sort.then_some(name.width()); let maybe_lowercase_name = (!settings.case_sensitive).then_some(NatOrdStr(maybe_lowercase(name))); let module_name = NatOrdStr::from(name); @@ -141,6 +166,7 @@ impl<'a> MemberKey<'a> { Self { not_star_import, member_type, + maybe_length, maybe_lowercase_name, module_name, asname, diff --git a/crates/ruff_linter/src/rules/pep8_naming/helpers.rs b/crates/ruff_linter/src/rules/pep8_naming/helpers.rs index 6d09971253201..b48388935cfff 100644 --- a/crates/ruff_linter/src/rules/pep8_naming/helpers.rs +++ b/crates/ruff_linter/src/rules/pep8_naming/helpers.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use ruff_python_ast::call_path::collect_call_path; use ruff_python_ast::{self as ast, Arguments, Expr, Stmt}; use ruff_python_semantic::SemanticModel; @@ -63,12 +64,16 @@ pub(super) fn is_type_var_assignment(stmt: &Stmt, semantic: &SemanticModel) -> b /// Returns `true` if the statement is an assignment to a `TypeAlias`. pub(super) fn is_type_alias_assignment(stmt: &Stmt, semantic: &SemanticModel) -> bool { - let Stmt::AnnAssign(ast::StmtAnnAssign { annotation, .. }) = stmt else { - return false; - }; - semantic.match_typing_expr(annotation, "TypeAlias") + match stmt { + Stmt::AnnAssign(ast::StmtAnnAssign { annotation, .. }) => { + semantic.match_typing_expr(annotation, "TypeAlias") + } + Stmt::TypeAlias(_) => true, + _ => false, + } } +/// Returns `true` if the statement is an assignment to a `TypedDict`. pub(super) fn is_typed_dict_class(arguments: Option<&Arguments>, semantic: &SemanticModel) -> bool { arguments.is_some_and(|arguments| { arguments @@ -78,6 +83,77 @@ pub(super) fn is_typed_dict_class(arguments: Option<&Arguments>, semantic: &Sema }) } +/// Returns `true` if a statement appears to be a dynamic import of a Django model. +/// +/// For example, in Django, it's common to use `get_model` to access a model dynamically, as in: +/// ```python +/// def migrate_existing_attachment_data( +/// apps: StateApps, schema_editor: BaseDatabaseSchemaEditor +/// ) -> None: +/// Attachment = apps.get_model("zerver", "Attachment") +/// ``` +pub(super) fn is_django_model_import(name: &str, stmt: &Stmt, semantic: &SemanticModel) -> bool { + fn match_model_import(name: &str, expr: &Expr, semantic: &SemanticModel) -> bool { + let Expr::Call(ast::ExprCall { + func, arguments, .. + }) = expr + else { + return false; + }; + + if arguments.is_empty() { + return false; + } + + // Match against, e.g., `apps.get_model("zerver", "Attachment")`. + if let Some(call_path) = collect_call_path(func.as_ref()) { + if matches!(call_path.as_slice(), [.., "get_model"]) { + if let Some(argument) = + arguments.find_argument("model_name", arguments.args.len().saturating_sub(1)) + { + if let Some(string_literal) = argument.as_string_literal_expr() { + if string_literal.value.to_str() == name { + return true; + } + } else { + return true; + } + } + } + } + + // Match against, e.g., `import_string("zerver.models.Attachment")`. + if let Some(call_path) = semantic.resolve_call_path(func.as_ref()) { + if matches!( + call_path.as_slice(), + ["django", "utils", "module_loading", "import_string"] + ) { + if let Some(argument) = arguments.find_argument("dotted_path", 0) { + if let Some(string_literal) = argument.as_string_literal_expr() { + if let Some((.., model)) = string_literal.value.to_str().rsplit_once('.') { + if model == name { + return true; + } + } + } + } + } + } + + false + } + + match stmt { + Stmt::AnnAssign(ast::StmtAnnAssign { + value: Some(value), .. + }) => match_model_import(name, value.as_ref(), semantic), + Stmt::Assign(ast::StmtAssign { value, .. }) => { + match_model_import(name, value.as_ref(), semantic) + } + _ => false, + } +} + #[cfg(test)] mod tests { use super::{is_acronym, is_camelcase, is_mixed_case}; diff --git a/crates/ruff_linter/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs b/crates/ruff_linter/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs index 59df8bf60eeae..3e073f343c9c9 100644 --- a/crates/ruff_linter/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs +++ b/crates/ruff_linter/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs @@ -53,6 +53,15 @@ impl Violation for NonLowercaseVariableInFunction { /// N806 pub(crate) fn non_lowercase_variable_in_function(checker: &mut Checker, expr: &Expr, name: &str) { + // Ignore globals. + if checker + .semantic() + .lookup_symbol(name) + .is_some_and(|id| checker.semantic().binding(id).is_global()) + { + return; + } + if checker .settings .pep8_naming @@ -72,6 +81,7 @@ pub(crate) fn non_lowercase_variable_in_function(checker: &mut Checker, expr: &E || helpers::is_typed_dict_assignment(parent, checker.semantic()) || helpers::is_type_var_assignment(parent, checker.semantic()) || helpers::is_type_alias_assignment(parent, checker.semantic()) + || helpers::is_django_model_import(name, parent, checker.semantic()) { return; } diff --git a/crates/ruff_linter/src/rules/pep8_naming/snapshots/ruff_linter__rules__pep8_naming__tests__N806_N806.py.snap b/crates/ruff_linter/src/rules/pep8_naming/snapshots/ruff_linter__rules__pep8_naming__tests__N806_N806.py.snap index 16718b5a9938b..1baa39c61040b 100644 --- a/crates/ruff_linter/src/rules/pep8_naming/snapshots/ruff_linter__rules__pep8_naming__tests__N806_N806.py.snap +++ b/crates/ruff_linter/src/rules/pep8_naming/snapshots/ruff_linter__rules__pep8_naming__tests__N806_N806.py.snap @@ -20,4 +20,47 @@ N806.py:13:5: N806 Variable `CONSTANT` in function should be lowercase 14 | _ = 0 | +N806.py:46:5: N806 Variable `Bad` in function should be lowercase + | +45 | def model_assign() -> None: +46 | Bad = apps.get_model("zerver", "Stream") # N806 + | ^^^ N806 +47 | Attachment = apps.get_model("zerver", "Attachment") # OK +48 | Recipient = apps.get_model("zerver", model_name="Recipient") # OK + | + +N806.py:53:5: N806 Variable `Bad` in function should be lowercase + | +51 | from django.utils.module_loading import import_string +52 | +53 | Bad = import_string("django.core.exceptions.ValidationError") # N806 + | ^^^ N806 +54 | ValidationError = import_string("django.core.exceptions.ValidationError") # OK + | + +N806.py:56:5: N806 Variable `Bad` in function should be lowercase + | +54 | ValidationError = import_string("django.core.exceptions.ValidationError") # OK +55 | +56 | Bad = apps.get_model() # N806 + | ^^^ N806 +57 | Bad = apps.get_model(model_name="Stream") # N806 + | + +N806.py:57:5: N806 Variable `Bad` in function should be lowercase + | +56 | Bad = apps.get_model() # N806 +57 | Bad = apps.get_model(model_name="Stream") # N806 + | ^^^ N806 +58 | +59 | Address: Type = apps.get_model("zerver", variable) # OK + | + +N806.py:60:5: N806 Variable `ValidationError` in function should be lowercase + | +59 | Address: Type = apps.get_model("zerver", variable) # OK +60 | ValidationError = import_string(variable) # N806 + | ^^^^^^^^^^^^^^^ N806 + | + diff --git a/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs b/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs index 9769eed8d71e3..4c73fd4800ecb 100644 --- a/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs +++ b/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs @@ -1,7 +1,7 @@ use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::Stmt; -use ruff_python_ast::{self as ast, Arguments, Expr}; +use ruff_python_ast::{self as ast, Arguments, Expr, Stmt}; +use ruff_python_semantic::analyze::typing::find_assigned_value; use ruff_text_size::TextRange; use crate::checkers::ast::Checker; @@ -49,7 +49,7 @@ impl AlwaysFixableViolation for UnnecessaryListCast { } /// PERF101 -pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr) { +pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr, body: &[Stmt]) { let Expr::Call(ast::ExprCall { func, arguments: @@ -98,36 +98,53 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr) { range: iterable_range, .. }) => { - let scope = checker.semantic().current_scope(); - if let Some(binding_id) = scope.get(id) { - let binding = checker.semantic().binding(binding_id); - if binding.kind.is_assignment() || binding.kind.is_named_expr_assignment() { - if let Some(parent_id) = binding.source { - let parent = checker.semantic().statement(parent_id); - if let Stmt::Assign(ast::StmtAssign { value, .. }) - | Stmt::AnnAssign(ast::StmtAnnAssign { - value: Some(value), .. - }) - | Stmt::AugAssign(ast::StmtAugAssign { value, .. }) = parent - { - if matches!( - value.as_ref(), - Expr::Tuple(_) | Expr::List(_) | Expr::Set(_) - ) { - let mut diagnostic = - Diagnostic::new(UnnecessaryListCast, *list_range); - diagnostic.set_fix(remove_cast(*list_range, *iterable_range)); - checker.diagnostics.push(diagnostic); - } - } - } - } + // If the variable is being appended to, don't suggest removing the cast: + // + // ```python + // items = ["foo", "bar"] + // for item in list(items): + // items.append("baz") + // ``` + // + // Here, removing the `list()` cast would change the behavior of the code. + if body.iter().any(|stmt| match_append(stmt, id)) { + return; + } + let Some(value) = find_assigned_value(id, checker.semantic()) else { + return; + }; + if matches!(value, Expr::Tuple(_) | Expr::List(_) | Expr::Set(_)) { + let mut diagnostic = Diagnostic::new(UnnecessaryListCast, *list_range); + diagnostic.set_fix(remove_cast(*list_range, *iterable_range)); + checker.diagnostics.push(diagnostic); } } _ => {} } } +/// Check if a statement is an `append` call to a given identifier. +/// +/// For example, `foo.append(bar)` would return `true` if `id` is `foo`. +fn match_append(stmt: &Stmt, id: &str) -> bool { + let Some(ast::StmtExpr { value, .. }) = stmt.as_expr_stmt() else { + return false; + }; + let Some(ast::ExprCall { func, .. }) = value.as_call_expr() else { + return false; + }; + let Some(ast::ExprAttribute { value, attr, .. }) = func.as_attribute_expr() else { + return false; + }; + if attr != "append" { + return false; + } + let Some(ast::ExprName { id: target_id, .. }) = value.as_name_expr() else { + return false; + }; + target_id == id +} + /// Generate a [`Fix`] to remove a `list` cast from an expression. fn remove_cast(list_range: TextRange, iterable_range: TextRange) -> Fix { Fix::safe_edits( diff --git a/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF101_PERF101.py.snap b/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF101_PERF101.py.snap index 645b5e5177784..11dafc4dd2565 100644 --- a/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF101_PERF101.py.snap +++ b/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF101_PERF101.py.snap @@ -180,4 +180,43 @@ PERF101.py:34:10: PERF101 [*] Do not cast an iterable to `list` before iterating 38 36 | 39 37 | for i in list(foo_dict): # Ok +PERF101.py:57:10: PERF101 [*] Do not cast an iterable to `list` before iterating over it + | +55 | foo_list.append(i + 1) +56 | +57 | for i in list(foo_list): # PERF101 + | ^^^^^^^^^^^^^^ PERF101 +58 | # Make sure we match the correct list +59 | other_list.append(i + 1) + | + = help: Remove `list()` cast + +ℹ Safe fix +54 54 | for i in list(foo_list): # Ok +55 55 | foo_list.append(i + 1) +56 56 | +57 |-for i in list(foo_list): # PERF101 + 57 |+for i in foo_list: # PERF101 +58 58 | # Make sure we match the correct list +59 59 | other_list.append(i + 1) +60 60 | + +PERF101.py:69:10: PERF101 [*] Do not cast an iterable to `list` before iterating over it + | +67 | x, y, nested_tuple = (1, 2, (3, 4, 5)) +68 | +69 | for i in list(nested_tuple): # PERF101 + | ^^^^^^^^^^^^^^^^^^ PERF101 +70 | pass + | + = help: Remove `list()` cast + +ℹ Safe fix +66 66 | +67 67 | x, y, nested_tuple = (1, 2, (3, 4, 5)) +68 68 | +69 |-for i in list(nested_tuple): # PERF101 + 69 |+for i in nested_tuple: # PERF101 +70 70 | pass + diff --git a/crates/ruff_linter/src/rules/pycodestyle/mod.rs b/crates/ruff_linter/src/rules/pycodestyle/mod.rs index ef1502d9d8240..c2d3a1d912b74 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/mod.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/mod.rs @@ -31,12 +31,12 @@ mod tests { #[test_case(Rule::BlankLineWithWhitespace, Path::new("W29.py"))] #[test_case(Rule::InvalidEscapeSequence, Path::new("W605_0.py"))] #[test_case(Rule::InvalidEscapeSequence, Path::new("W605_1.py"))] - #[test_case(Rule::InvalidEscapeSequence, Path::new("W605_2.py"))] #[test_case(Rule::LineTooLong, Path::new("E501.py"))] #[test_case(Rule::LineTooLong, Path::new("E501_3.py"))] #[test_case(Rule::MixedSpacesAndTabs, Path::new("E101.py"))] #[test_case(Rule::ModuleImportNotAtTopOfFile, Path::new("E40.py"))] #[test_case(Rule::ModuleImportNotAtTopOfFile, Path::new("E402.py"))] + #[test_case(Rule::ModuleImportNotAtTopOfFile, Path::new("E402.ipynb"))] #[test_case(Rule::MultipleImportsOnOneLine, Path::new("E40.py"))] #[test_case(Rule::MultipleStatementsOnOneLineColon, Path::new("E70.py"))] #[test_case(Rule::MultipleStatementsOnOneLineSemicolon, Path::new("E70.py"))] @@ -53,6 +53,7 @@ mod tests { #[test_case(Rule::TrueFalseComparison, Path::new("E712.py"))] #[test_case(Rule::TypeComparison, Path::new("E721.py"))] #[test_case(Rule::UselessSemicolon, Path::new("E70.py"))] + #[test_case(Rule::UselessSemicolon, Path::new("E703.ipynb"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( @@ -64,6 +65,7 @@ mod tests { } #[test_case(Rule::IsLiteral, Path::new("constant_literals.py"))] + #[test_case(Rule::ModuleImportNotAtTopOfFile, Path::new("E402.py"))] #[test_case(Rule::TypeComparison, Path::new("E721.py"))] fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!( diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/compound_statements.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/compound_statements.rs index 6dcdd19c8b4ec..2b7434dd23c17 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/compound_statements.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/compound_statements.rs @@ -1,6 +1,8 @@ +use ruff_notebook::CellOffsets; +use ruff_python_ast::PySourceType; use ruff_python_parser::lexer::LexResult; use ruff_python_parser::Tok; -use ruff_text_size::TextRange; +use ruff_text_size::{TextRange, TextSize}; use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; @@ -101,6 +103,8 @@ pub(crate) fn compound_statements( lxr: &[LexResult], locator: &Locator, indexer: &Indexer, + source_type: PySourceType, + cell_offsets: Option<&CellOffsets>, ) { // Track the last seen instance of a variety of tokens. let mut colon = None; @@ -127,7 +131,13 @@ pub(crate) fn compound_statements( let mut sqb_count = 0u32; let mut brace_count = 0u32; - for &(ref tok, range) in lxr.iter().flatten() { + // Track indentation. + let mut indent = 0u32; + + // Keep the token iterator to perform lookaheads. + let mut tokens = lxr.iter().flatten(); + + while let Some(&(ref tok, range)) = tokens.next() { match tok { Tok::Lpar => { par_count = par_count.saturating_add(1); @@ -153,6 +163,12 @@ pub(crate) fn compound_statements( continue; } } + Tok::Indent => { + indent = indent.saturating_add(1); + } + Tok::Dedent => { + indent = indent.saturating_sub(1); + } _ => {} } @@ -163,15 +179,24 @@ pub(crate) fn compound_statements( match tok { Tok::Newline => { if let Some((start, end)) = semi { - let mut diagnostic = - Diagnostic::new(UselessSemicolon, TextRange::new(start, end)); - diagnostic.set_fix(Fix::safe_edit(Edit::deletion( - indexer - .preceded_by_continuations(start, locator) - .unwrap_or(start), - end, - ))); - diagnostics.push(diagnostic); + if !(source_type.is_ipynb() + && indent == 0 + && cell_offsets + .and_then(|cell_offsets| cell_offsets.containing_range(range.start())) + .is_some_and(|cell_range| { + !has_non_trivia_tokens_till(tokens.clone(), cell_range.end()) + })) + { + let mut diagnostic = + Diagnostic::new(UselessSemicolon, TextRange::new(start, end)); + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + indexer + .preceded_by_continuations(start, locator) + .unwrap_or(start), + end, + ))); + diagnostics.push(diagnostic); + } } // Reset. @@ -309,3 +334,23 @@ pub(crate) fn compound_statements( }; } } + +/// Returns `true` if there are any non-trivia tokens from the given token +/// iterator till the given end offset. +fn has_non_trivia_tokens_till<'a>( + tokens: impl Iterator, + cell_end: TextSize, +) -> bool { + for &(ref tok, tok_range) in tokens { + if tok_range.start() >= cell_end { + return false; + } + if !matches!( + tok, + Tok::Newline | Tok::Comment(_) | Tok::EndOfFile | Tok::NonLogicalNewline + ) { + return true; + } + } + false +} diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/imports.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/imports.rs index 4a037d7d0d438..b85dc9eba8fb5 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/imports.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/imports.rs @@ -1,6 +1,6 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::{Alias, Stmt}; +use ruff_python_ast::{Alias, PySourceType, Stmt}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -34,12 +34,17 @@ impl Violation for MultipleImportsOnOneLine { } /// ## What it does -/// Checks for imports that are not at the top of the file. +/// Checks for imports that are not at the top of the file. For Jupyter notebooks, this +/// checks for imports that are not at the top of the cell. /// /// ## Why is this bad? /// According to [PEP 8], "imports are always put at the top of the file, just after any /// module comments and docstrings, and before module globals and constants." /// +/// In [preview], this rule makes an exception for `sys.path` modifications, +/// allowing for `sys.path.insert`, `sys.path.append`, and similar +/// modifications between import statements. +/// /// ## Example /// ```python /// "One string" @@ -61,12 +66,18 @@ impl Violation for MultipleImportsOnOneLine { /// /// [PEP 8]: https://peps.python.org/pep-0008/#imports #[violation] -pub struct ModuleImportNotAtTopOfFile; +pub struct ModuleImportNotAtTopOfFile { + source_type: PySourceType, +} impl Violation for ModuleImportNotAtTopOfFile { #[derive_message_formats] fn message(&self) -> String { - format!("Module level import not at top of file") + if self.source_type.is_ipynb() { + format!("Module level import not at top of cell") + } else { + format!("Module level import not at top of file") + } } } @@ -82,8 +93,11 @@ pub(crate) fn multiple_imports_on_one_line(checker: &mut Checker, stmt: &Stmt, n /// E402 pub(crate) fn module_import_not_at_top_of_file(checker: &mut Checker, stmt: &Stmt) { if checker.semantic().seen_import_boundary() && checker.semantic().at_top_level() { - checker - .diagnostics - .push(Diagnostic::new(ModuleImportNotAtTopOfFile, stmt.range())); + checker.diagnostics.push(Diagnostic::new( + ModuleImportNotAtTopOfFile { + source_type: checker.source_type, + }, + stmt.range(), + )); } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/invalid_escape_sequence.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/invalid_escape_sequence.rs index b4d100aa9d6f3..77a3d6ba621df 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/invalid_escape_sequence.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/invalid_escape_sequence.rs @@ -3,9 +3,9 @@ use memchr::memchr_iter; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_index::Indexer; -use ruff_python_parser::Tok; +use ruff_python_parser::{StringKind, Tok}; use ruff_source_file::Locator; -use ruff_text_size::{TextLen, TextRange, TextSize}; +use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use crate::fix::edits::pad_start; @@ -58,18 +58,6 @@ impl AlwaysFixableViolation for InvalidEscapeSequence { } } -#[derive(Debug, PartialEq, Eq)] -enum FixTitle { - AddBackslash, - UseRawStringLiteral, -} - -#[derive(Debug)] -struct InvalidEscapeChar { - ch: char, - range: TextRange, -} - /// W605 pub(crate) fn invalid_escape_sequence( diagnostics: &mut Vec, @@ -195,41 +183,77 @@ pub(crate) fn invalid_escape_sequence( if contains_valid_escape_sequence { // Escape with backslash. for invalid_escape_char in &invalid_escape_chars { - let diagnostic = Diagnostic::new( + let mut diagnostic = Diagnostic::new( InvalidEscapeSequence { ch: invalid_escape_char.ch, fix_title: FixTitle::AddBackslash, }, - invalid_escape_char.range, - ) - .with_fix(Fix::safe_edit(Edit::insertion( + invalid_escape_char.range(), + ); + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( r"\".to_string(), - invalid_escape_char.range.start() + TextSize::from(1), + invalid_escape_char.start() + TextSize::from(1), ))); invalid_escape_sequence.push(diagnostic); } } else { // Turn into raw string. for invalid_escape_char in &invalid_escape_chars { - let diagnostic = Diagnostic::new( + let mut diagnostic = Diagnostic::new( InvalidEscapeSequence { ch: invalid_escape_char.ch, fix_title: FixTitle::UseRawStringLiteral, }, - invalid_escape_char.range, - ) - .with_fix( - // If necessary, add a space between any leading keyword (`return`, `yield`, - // `assert`, etc.) and the string. For example, `return"foo"` is valid, but - // `returnr"foo"` is not. - Fix::safe_edit(Edit::insertion( - pad_start("r".to_string(), string_start_location, locator), - string_start_location, - )), + invalid_escape_char.range(), ); + + if matches!( + token, + Tok::String { + kind: StringKind::Unicode, + .. + } + ) { + // Replace the Unicode prefix with `r`. + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + "r".to_string(), + string_start_location, + string_start_location + TextSize::from(1), + ))); + } else { + // Insert the `r` prefix. + diagnostic.set_fix( + // If necessary, add a space between any leading keyword (`return`, `yield`, + // `assert`, etc.) and the string. For example, `return"foo"` is valid, but + // `returnr"foo"` is not. + Fix::safe_edit(Edit::insertion( + pad_start("r".to_string(), string_start_location, locator), + string_start_location, + )), + ); + } + invalid_escape_sequence.push(diagnostic); } } diagnostics.extend(invalid_escape_sequence); } + +#[derive(Debug, PartialEq, Eq)] +enum FixTitle { + AddBackslash, + UseRawStringLiteral, +} + +#[derive(Debug)] +struct InvalidEscapeChar { + ch: char, + range: TextRange, +} + +impl Ranged for InvalidEscapeChar { + fn range(&self) -> TextRange { + self.range + } +} diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/extraneous_whitespace.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/extraneous_whitespace.rs index bfc7bcaefd065..a4134e51cbb96 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/extraneous_whitespace.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/extraneous_whitespace.rs @@ -213,13 +213,28 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &mut LogicalLin diagnostic.range(), ))); context.push_diagnostic(diagnostic); + } else if iter + .peek() + .is_some_and(|token| token.kind() == TokenKind::Rsqb) + { + // Allow `foo[1 :]`, but not `foo[1 :]`. + if let (Whitespace::Many | Whitespace::Tab, offset) = whitespace + { + let mut diagnostic = Diagnostic::new( + WhitespaceBeforePunctuation { symbol }, + TextRange::at(token.start() - offset, offset), + ); + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion( + diagnostic.range(), + ))); + context.push_diagnostic(diagnostic); + } } else { + // Allow, e.g., `foo[1:2]` or `foo[1 : 2]` or `foo[1 :: 2]`. let token = iter .peek() .filter(|next| matches!(next.kind(), TokenKind::Colon)) .unwrap_or(&token); - - // Allow, e.g., `foo[1:2]` or `foo[1 : 2]` or `foo[1 :: 2]`. if line.trailing_whitespace(token) != whitespace { let mut diagnostic = Diagnostic::new( WhitespaceBeforePunctuation { symbol }, diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs index 4a8bb4befd821..b667ebee151e5 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs @@ -383,20 +383,16 @@ impl Whitespace { } } - if has_tabs { + if len == content.text_len() { + // All whitespace up to the start of the line -> Indent + (Self::None, TextSize::default()) + } else if has_tabs { (Self::Tab, len) } else { match count { 0 => (Self::None, TextSize::default()), 1 => (Self::Single, len), - _ => { - if len == content.text_len() { - // All whitespace up to the start of the line -> Indent - (Self::None, TextSize::default()) - } else { - (Self::Many, len) - } - } + _ => (Self::Many, len), } } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_named_parameter_equals.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_named_parameter_equals.rs index f5baea15080dc..a0c4f49bf2250 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_named_parameter_equals.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_named_parameter_equals.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_text_size::{Ranged, TextRange, TextSize}; @@ -34,11 +34,15 @@ use crate::rules::pycodestyle::rules::logical_lines::{LogicalLine, LogicalLineTo #[violation] pub struct UnexpectedSpacesAroundKeywordParameterEquals; -impl Violation for UnexpectedSpacesAroundKeywordParameterEquals { +impl AlwaysFixableViolation for UnexpectedSpacesAroundKeywordParameterEquals { #[derive_message_formats] fn message(&self) -> String { format!("Unexpected spaces around keyword / parameter equals") } + + fn fix_title(&self) -> String { + format!("Remove whitespace") + } } /// ## What it does @@ -165,22 +169,31 @@ pub(crate) fn whitespace_around_named_parameter_equals( } } } else { + // If there's space between the preceding token and the equals sign, report it. if token.start() != prev_end { - context.push( + let mut diagnostic = Diagnostic::new( UnexpectedSpacesAroundKeywordParameterEquals, TextRange::new(prev_end, token.start()), ); + diagnostic.set_fix(Fix::safe_edit(Edit::deletion(prev_end, token.start()))); + context.push_diagnostic(diagnostic); } + // If there's space between the equals sign and the following token, report it. while let Some(next) = iter.peek() { if next.kind() == TokenKind::NonLogicalNewline { iter.next(); } else { if next.start() != token.end() { - context.push( + let mut diagnostic = Diagnostic::new( UnexpectedSpacesAroundKeywordParameterEquals, TextRange::new(token.end(), next.start()), ); + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + token.end(), + next.start(), + ))); + context.push_diagnostic(diagnostic); } break; } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_comment.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_comment.rs index 235c12f7b6c65..0df27d8fe583b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_comment.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_comment.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_python_trivia::PythonWhitespace; @@ -66,11 +66,15 @@ impl AlwaysFixableViolation for TooFewSpacesBeforeInlineComment { #[violation] pub struct NoSpaceAfterInlineComment; -impl Violation for NoSpaceAfterInlineComment { +impl AlwaysFixableViolation for NoSpaceAfterInlineComment { #[derive_message_formats] fn message(&self) -> String { format!("Inline comment should start with `# `") } + + fn fix_title(&self) -> String { + format!("Format space") + } } /// ## What it does @@ -98,11 +102,15 @@ impl Violation for NoSpaceAfterInlineComment { #[violation] pub struct NoSpaceAfterBlockComment; -impl Violation for NoSpaceAfterBlockComment { +impl AlwaysFixableViolation for NoSpaceAfterBlockComment { #[derive_message_formats] fn message(&self) -> String { format!("Block comment should start with `# `") } + + fn fix_title(&self) -> String { + format!("Format space") + } } /// ## What it does @@ -130,11 +138,15 @@ impl Violation for NoSpaceAfterBlockComment { #[violation] pub struct MultipleLeadingHashesForBlockComment; -impl Violation for MultipleLeadingHashesForBlockComment { +impl AlwaysFixableViolation for MultipleLeadingHashesForBlockComment { #[derive_message_formats] fn message(&self) -> String { format!("Too many leading `#` before block comment") } + + fn fix_title(&self) -> String { + format!("Remove leading `#`") + } } /// E261, E262, E265, E266 @@ -184,14 +196,30 @@ pub(crate) fn whitespace_before_comment( if is_inline_comment { if bad_prefix.is_some() || comment.chars().next().is_some_and(char::is_whitespace) { - context.push(NoSpaceAfterInlineComment, range); + let mut diagnostic = Diagnostic::new(NoSpaceAfterInlineComment, range); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format_leading_space(token_text), + range, + ))); + context.push_diagnostic(diagnostic); } } else if let Some(bad_prefix) = bad_prefix { if bad_prefix != '!' || !line.is_start_of_file() { if bad_prefix != '#' { - context.push(NoSpaceAfterBlockComment, range); + let mut diagnostic = Diagnostic::new(NoSpaceAfterBlockComment, range); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format_leading_space(token_text), + range, + ))); + context.push_diagnostic(diagnostic); } else if !comment.is_empty() { - context.push(MultipleLeadingHashesForBlockComment, range); + let mut diagnostic = + Diagnostic::new(MultipleLeadingHashesForBlockComment, range); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format_leading_hashes(token_text), + range, + ))); + context.push_diagnostic(diagnostic); } } } @@ -200,3 +228,17 @@ pub(crate) fn whitespace_before_comment( } } } + +/// Format a comment to have a single space after the `#`. +fn format_leading_space(comment: &str) -> String { + if let Some(rest) = comment.strip_prefix("#:") { + format!("#: {}", rest.trim_start()) + } else { + format!("# {}", comment.trim_start_matches('#').trim_start()) + } +} + +/// Format a comment to strip multiple leading `#` characters. +fn format_leading_hashes(comment: &str) -> String { + format!("# {}", comment.trim_start_matches('#').trim_start()) +} diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E202_E20.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E202_E20.py.snap index 67d7bc6e28897..971a719f3da44 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E202_E20.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E202_E20.py.snap @@ -146,4 +146,24 @@ E20.py:90:18: E202 [*] Whitespace before ']' 92 92 | 93 93 | #: Okay +E20.py:146:12: E202 [*] Whitespace before ']' + | +145 | #: E202:1:12 +146 | ham[upper : ] + | ^ E202 +147 | +148 | #: E203:1:10 + | + = help: Remove whitespace before ']' + +ℹ Safe fix +143 143 | ham[upper :] +144 144 | +145 145 | #: E202:1:12 +146 |-ham[upper : ] + 146 |+ham[upper :] +147 147 | +148 148 | #: E203:1:10 +149 149 | ham[upper :] + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E203_E20.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E203_E20.py.snap index c81fa5d87894a..d92741af055a6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E203_E20.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E203_E20.py.snap @@ -211,6 +211,8 @@ E20.py:137:20: E203 [*] Whitespace before ':' 136 | #: E203:1:20 137 | ham[{lower + offset : upper + offset} : upper + offset] | ^ E203 +138 | +139 | #: Okay | = help: Remove whitespace before ':' @@ -220,5 +222,23 @@ E20.py:137:20: E203 [*] Whitespace before ':' 136 136 | #: E203:1:20 137 |-ham[{lower + offset : upper + offset} : upper + offset] 137 |+ham[{lower + offset: upper + offset} : upper + offset] +138 138 | +139 139 | #: Okay +140 140 | ham[upper:] + +E20.py:149:10: E203 [*] Whitespace before ':' + | +148 | #: E203:1:10 +149 | ham[upper :] + | ^^ E203 + | + = help: Remove whitespace before ':' + +ℹ Safe fix +146 146 | ham[upper : ] +147 147 | +148 148 | #: E203:1:10 +149 |-ham[upper :] + 149 |+ham[upper:] diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E251_E25.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E251_E25.py.snap index 88d211954bd9b..a87bcdff5586b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E251_E25.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E251_E25.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E25.py:2:12: E251 Unexpected spaces around keyword / parameter equals +E25.py:2:12: E251 [*] Unexpected spaces around keyword / parameter equals | 1 | #: E251 E251 2 | def foo(bar = False): @@ -9,8 +9,17 @@ E25.py:2:12: E251 Unexpected spaces around keyword / parameter equals 3 | '''Test function with an error in declaration''' 4 | pass | + = help: Remove whitespace -E25.py:2:14: E251 Unexpected spaces around keyword / parameter equals +ℹ Safe fix +1 1 | #: E251 E251 +2 |-def foo(bar = False): + 2 |+def foo(bar= False): +3 3 | '''Test function with an error in declaration''' +4 4 | pass +5 5 | #: E251 + +E25.py:2:14: E251 [*] Unexpected spaces around keyword / parameter equals | 1 | #: E251 E251 2 | def foo(bar = False): @@ -18,8 +27,17 @@ E25.py:2:14: E251 Unexpected spaces around keyword / parameter equals 3 | '''Test function with an error in declaration''' 4 | pass | + = help: Remove whitespace + +ℹ Safe fix +1 1 | #: E251 E251 +2 |-def foo(bar = False): + 2 |+def foo(bar =False): +3 3 | '''Test function with an error in declaration''' +4 4 | pass +5 5 | #: E251 -E25.py:6:9: E251 Unexpected spaces around keyword / parameter equals +E25.py:6:9: E251 [*] Unexpected spaces around keyword / parameter equals | 4 | pass 5 | #: E251 @@ -28,8 +46,19 @@ E25.py:6:9: E251 Unexpected spaces around keyword / parameter equals 7 | #: E251 8 | foo(bar =True) | + = help: Remove whitespace + +ℹ Safe fix +3 3 | '''Test function with an error in declaration''' +4 4 | pass +5 5 | #: E251 +6 |-foo(bar= True) + 6 |+foo(bar=True) +7 7 | #: E251 +8 8 | foo(bar =True) +9 9 | #: E251 E251 -E25.py:8:8: E251 Unexpected spaces around keyword / parameter equals +E25.py:8:8: E251 [*] Unexpected spaces around keyword / parameter equals | 6 | foo(bar= True) 7 | #: E251 @@ -38,8 +67,19 @@ E25.py:8:8: E251 Unexpected spaces around keyword / parameter equals 9 | #: E251 E251 10 | foo(bar = True) | + = help: Remove whitespace -E25.py:10:8: E251 Unexpected spaces around keyword / parameter equals +ℹ Safe fix +5 5 | #: E251 +6 6 | foo(bar= True) +7 7 | #: E251 +8 |-foo(bar =True) + 8 |+foo(bar=True) +9 9 | #: E251 E251 +10 10 | foo(bar = True) +11 11 | #: E251 + +E25.py:10:8: E251 [*] Unexpected spaces around keyword / parameter equals | 8 | foo(bar =True) 9 | #: E251 E251 @@ -48,8 +88,19 @@ E25.py:10:8: E251 Unexpected spaces around keyword / parameter equals 11 | #: E251 12 | y = bar(root= "sdasd") | + = help: Remove whitespace + +ℹ Safe fix +7 7 | #: E251 +8 8 | foo(bar =True) +9 9 | #: E251 E251 +10 |-foo(bar = True) + 10 |+foo(bar= True) +11 11 | #: E251 +12 12 | y = bar(root= "sdasd") +13 13 | #: E251:2:29 -E25.py:10:10: E251 Unexpected spaces around keyword / parameter equals +E25.py:10:10: E251 [*] Unexpected spaces around keyword / parameter equals | 8 | foo(bar =True) 9 | #: E251 E251 @@ -58,8 +109,19 @@ E25.py:10:10: E251 Unexpected spaces around keyword / parameter equals 11 | #: E251 12 | y = bar(root= "sdasd") | + = help: Remove whitespace + +ℹ Safe fix +7 7 | #: E251 +8 8 | foo(bar =True) +9 9 | #: E251 E251 +10 |-foo(bar = True) + 10 |+foo(bar =True) +11 11 | #: E251 +12 12 | y = bar(root= "sdasd") +13 13 | #: E251:2:29 -E25.py:12:14: E251 Unexpected spaces around keyword / parameter equals +E25.py:12:14: E251 [*] Unexpected spaces around keyword / parameter equals | 10 | foo(bar = True) 11 | #: E251 @@ -68,8 +130,19 @@ E25.py:12:14: E251 Unexpected spaces around keyword / parameter equals 13 | #: E251:2:29 14 | parser.add_argument('--long-option', | + = help: Remove whitespace -E25.py:15:29: E251 Unexpected spaces around keyword / parameter equals +ℹ Safe fix +9 9 | #: E251 E251 +10 10 | foo(bar = True) +11 11 | #: E251 +12 |-y = bar(root= "sdasd") + 12 |+y = bar(root="sdasd") +13 13 | #: E251:2:29 +14 14 | parser.add_argument('--long-option', +15 15 | default= + +E25.py:15:29: E251 [*] Unexpected spaces around keyword / parameter equals | 13 | #: E251:2:29 14 | parser.add_argument('--long-option', @@ -80,8 +153,20 @@ E25.py:15:29: E251 Unexpected spaces around keyword / parameter equals 17 | #: E251:1:45 18 | parser.add_argument('--long-option', default | + = help: Remove whitespace + +ℹ Safe fix +12 12 | y = bar(root= "sdasd") +13 13 | #: E251:2:29 +14 14 | parser.add_argument('--long-option', +15 |- default= +16 |- "/rather/long/filesystem/path/here/blah/blah/blah") + 15 |+ default="/rather/long/filesystem/path/here/blah/blah/blah") +17 16 | #: E251:1:45 +18 17 | parser.add_argument('--long-option', default +19 18 | ="/rather/long/filesystem/path/here/blah/blah/blah") -E25.py:18:45: E251 Unexpected spaces around keyword / parameter equals +E25.py:18:45: E251 [*] Unexpected spaces around keyword / parameter equals | 16 | "/rather/long/filesystem/path/here/blah/blah/blah") 17 | #: E251:1:45 @@ -92,8 +177,20 @@ E25.py:18:45: E251 Unexpected spaces around keyword / parameter equals 20 | #: E251:3:8 E251:3:10 21 | foo(True, | + = help: Remove whitespace + +ℹ Safe fix +15 15 | default= +16 16 | "/rather/long/filesystem/path/here/blah/blah/blah") +17 17 | #: E251:1:45 +18 |-parser.add_argument('--long-option', default +19 |- ="/rather/long/filesystem/path/here/blah/blah/blah") + 18 |+parser.add_argument('--long-option', default="/rather/long/filesystem/path/here/blah/blah/blah") +20 19 | #: E251:3:8 E251:3:10 +21 20 | foo(True, +22 21 | baz=(1, 2), -E25.py:23:8: E251 Unexpected spaces around keyword / parameter equals +E25.py:23:8: E251 [*] Unexpected spaces around keyword / parameter equals | 21 | foo(True, 22 | baz=(1, 2), @@ -102,8 +199,19 @@ E25.py:23:8: E251 Unexpected spaces around keyword / parameter equals 24 | ) 25 | #: Okay | + = help: Remove whitespace -E25.py:23:10: E251 Unexpected spaces around keyword / parameter equals +ℹ Safe fix +20 20 | #: E251:3:8 E251:3:10 +21 21 | foo(True, +22 22 | baz=(1, 2), +23 |- biz = 'foo' + 23 |+ biz= 'foo' +24 24 | ) +25 25 | #: Okay +26 26 | foo(bar=(1 == 1)) + +E25.py:23:10: E251 [*] Unexpected spaces around keyword / parameter equals | 21 | foo(True, 22 | baz=(1, 2), @@ -112,5 +220,16 @@ E25.py:23:10: E251 Unexpected spaces around keyword / parameter equals 24 | ) 25 | #: Okay | + = help: Remove whitespace + +ℹ Safe fix +20 20 | #: E251:3:8 E251:3:10 +21 21 | foo(True, +22 22 | baz=(1, 2), +23 |- biz = 'foo' + 23 |+ biz ='foo' +24 24 | ) +25 25 | #: Okay +26 26 | foo(bar=(1 == 1)) diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E262_E26.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E262_E26.py.snap index a01a1eb2d7cd1..658391acdc36b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E262_E26.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E262_E26.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E26.py:4:12: E262 Inline comment should start with `# ` +E26.py:4:12: E262 [*] Inline comment should start with `# ` | 2 | pass # an inline comment 3 | #: E262:1:12 @@ -10,8 +10,19 @@ E26.py:4:12: E262 Inline comment should start with `# ` 5 | #: E262:1:12 6 | x = x + 1 # Increment x | + = help: Format space -E26.py:6:12: E262 Inline comment should start with `# ` +ℹ Safe fix +1 1 | #: E261:1:5 +2 2 | pass # an inline comment +3 3 | #: E262:1:12 +4 |-x = x + 1 #Increment x + 4 |+x = x + 1 # Increment x +5 5 | #: E262:1:12 +6 6 | x = x + 1 # Increment x +7 7 | #: E262:1:12 + +E26.py:6:12: E262 [*] Inline comment should start with `# ` | 4 | x = x + 1 #Increment x 5 | #: E262:1:12 @@ -20,8 +31,19 @@ E26.py:6:12: E262 Inline comment should start with `# ` 7 | #: E262:1:12 8 | x = y + 1 #: Increment x | + = help: Format space + +ℹ Safe fix +3 3 | #: E262:1:12 +4 4 | x = x + 1 #Increment x +5 5 | #: E262:1:12 +6 |-x = x + 1 # Increment x + 6 |+x = x + 1 # Increment x +7 7 | #: E262:1:12 +8 8 | x = y + 1 #: Increment x +9 9 | #: E265:1:1 -E26.py:8:12: E262 Inline comment should start with `# ` +E26.py:8:12: E262 [*] Inline comment should start with `# ` | 6 | x = x + 1 # Increment x 7 | #: E262:1:12 @@ -30,8 +52,19 @@ E26.py:8:12: E262 Inline comment should start with `# ` 9 | #: E265:1:1 10 | #Block comment | + = help: Format space -E26.py:63:9: E262 Inline comment should start with `# ` +ℹ Safe fix +5 5 | #: E262:1:12 +6 6 | x = x + 1 # Increment x +7 7 | #: E262:1:12 +8 |-x = y + 1 #: Increment x + 8 |+x = y + 1 #: Increment x +9 9 | #: E265:1:1 +10 10 | #Block comment +11 11 | a = 1 + +E26.py:63:9: E262 [*] Inline comment should start with `# ` | 61 | # -*- coding: utf8 -*- 62 | #  (One space one NBSP) Ok for block comment @@ -40,8 +73,19 @@ E26.py:63:9: E262 Inline comment should start with `# ` 64 | #: E262:2:9 65 | # (Two spaces) Ok for block comment | + = help: Format space + +ℹ Safe fix +60 60 | #: E262:3:9 +61 61 | # -*- coding: utf8 -*- +62 62 | #  (One space one NBSP) Ok for block comment +63 |-a = 42 #  (One space one NBSP) + 63 |+a = 42 # (One space one NBSP) +64 64 | #: E262:2:9 +65 65 | # (Two spaces) Ok for block comment +66 66 | a = 42 # (Two spaces) -E26.py:66:9: E262 Inline comment should start with `# ` +E26.py:66:9: E262 [*] Inline comment should start with `# ` | 64 | #: E262:2:9 65 | # (Two spaces) Ok for block comment @@ -50,5 +94,52 @@ E26.py:66:9: E262 Inline comment should start with `# ` 67 | 68 | #: E265:5:1 | + = help: Format space + +ℹ Safe fix +63 63 | a = 42 #  (One space one NBSP) +64 64 | #: E262:2:9 +65 65 | # (Two spaces) Ok for block comment +66 |-a = 42 # (Two spaces) + 66 |+a = 42 # (Two spaces) +67 67 | +68 68 | #: E265:5:1 +69 69 | ### Means test is not done yet + +E26.py:84:8: E262 [*] Inline comment should start with `# ` + | +82 | ## Foo +83 | +84 | a = 1 ## Foo + | ^^^^^^ E262 +85 | +86 | a = 1 #:Foo + | + = help: Format space + +ℹ Safe fix +81 81 | #: E266:1:3 +82 82 | ## Foo +83 83 | +84 |-a = 1 ## Foo + 84 |+a = 1 # Foo +85 85 | +86 86 | a = 1 #:Foo + +E26.py:86:8: E262 [*] Inline comment should start with `# ` + | +84 | a = 1 ## Foo +85 | +86 | a = 1 #:Foo + | ^^^^^ E262 + | + = help: Format space + +ℹ Safe fix +83 83 | +84 84 | a = 1 ## Foo +85 85 | +86 |-a = 1 #:Foo + 86 |+a = 1 #: Foo diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E265_E26.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E265_E26.py.snap index 6017827141782..92b25ccb212b6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E265_E26.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E265_E26.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E26.py:10:1: E265 Block comment should start with `# ` +E26.py:10:1: E265 [*] Block comment should start with `# ` | 8 | x = y + 1 #: Increment x 9 | #: E265:1:1 @@ -10,8 +10,19 @@ E26.py:10:1: E265 Block comment should start with `# ` 11 | a = 1 12 | #: E265:2:1 | + = help: Format space -E26.py:14:1: E265 Block comment should start with `# ` +ℹ Safe fix +7 7 | #: E262:1:12 +8 8 | x = y + 1 #: Increment x +9 9 | #: E265:1:1 +10 |-#Block comment + 10 |+# Block comment +11 11 | a = 1 +12 12 | #: E265:2:1 +13 13 | m = 42 + +E26.py:14:1: E265 [*] Block comment should start with `# ` | 12 | #: E265:2:1 13 | m = 42 @@ -20,8 +31,19 @@ E26.py:14:1: E265 Block comment should start with `# ` 15 | mx = 42 - 42 16 | #: E266:3:5 E266:6:5 | + = help: Format space + +ℹ Safe fix +11 11 | a = 1 +12 12 | #: E265:2:1 +13 13 | m = 42 +14 |-#! This is important + 14 |+# ! This is important +15 15 | mx = 42 - 42 +16 16 | #: E266:3:5 E266:6:5 +17 17 | def how_it_feel(r): -E26.py:25:1: E265 Block comment should start with `# ` +E26.py:25:1: E265 [*] Block comment should start with `# ` | 23 | return 24 | #: E265:1:1 E266:2:1 @@ -30,8 +52,19 @@ E26.py:25:1: E265 Block comment should start with `# ` 26 | ## logging.error() 27 | #: W291:1:42 | + = help: Format space + +ℹ Safe fix +22 22 | ### Of course it is unused +23 23 | return +24 24 | #: E265:1:1 E266:2:1 +25 |-##if DEBUG: + 25 |+# if DEBUG: +26 26 | ## logging.error() +27 27 | #: W291:1:42 +28 28 | ######################################### -E26.py:32:1: E265 Block comment should start with `# ` +E26.py:32:1: E265 [*] Block comment should start with `# ` | 31 | #: Okay 32 | #!/usr/bin/env python @@ -39,8 +72,19 @@ E26.py:32:1: E265 Block comment should start with `# ` 33 | 34 | pass # an inline comment | + = help: Format space -E26.py:73:1: E265 Block comment should start with `# ` +ℹ Safe fix +29 29 | #: +30 30 | +31 31 | #: Okay +32 |-#!/usr/bin/env python + 32 |+# !/usr/bin/env python +33 33 | +34 34 | pass # an inline comment +35 35 | x = x + 1 # Increment x + +E26.py:73:1: E265 [*] Block comment should start with `# ` | 71 | # F Means test is failing (F) 72 | # EF Means test is giving error and Failing @@ -48,5 +92,37 @@ E26.py:73:1: E265 Block comment should start with `# ` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E265 74 | # 8 Means test runs forever | + = help: Format space + +ℹ Safe fix +70 70 | # E Means test is giving error (E) +71 71 | # F Means test is failing (F) +72 72 | # EF Means test is giving error and Failing +73 |-#! Means test is segfaulting + 73 |+# ! Means test is segfaulting +74 74 | # 8 Means test runs forever +75 75 | +76 76 | #: Colon prefix is okay + +E26.py:78:1: E265 [*] Block comment should start with `# ` + | +76 | #: Colon prefix is okay +77 | +78 | ###This is a variable ### + | ^^^^^^^^^^^^^^^^^^^^^^^^^ E265 +79 | +80 | # We should strip the space, but preserve the hashes. + | + = help: Format space + +ℹ Safe fix +75 75 | +76 76 | #: Colon prefix is okay +77 77 | +78 |-###This is a variable ### + 78 |+# This is a variable ### +79 79 | +80 80 | # We should strip the space, but preserve the hashes. +81 81 | #: E266:1:3 diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E266_E26.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E266_E26.py.snap index 5eb382385cccb..4469e1b225d64 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E266_E26.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E266_E26.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E26.py:19:5: E266 Too many leading `#` before block comment +E26.py:19:5: E266 [*] Too many leading `#` before block comment | 17 | def how_it_feel(r): 18 | @@ -9,8 +9,19 @@ E26.py:19:5: E266 Too many leading `#` before block comment | ^^^^^^^^^^^^^^^^^^^^^^^^^^ E266 20 | a = 42 | + = help: Remove leading `#` -E26.py:22:5: E266 Too many leading `#` before block comment +ℹ Safe fix +16 16 | #: E266:3:5 E266:6:5 +17 17 | def how_it_feel(r): +18 18 | +19 |- ### This is a variable ### + 19 |+ # This is a variable ### +20 20 | a = 42 +21 21 | +22 22 | ### Of course it is unused + +E26.py:22:5: E266 [*] Too many leading `#` before block comment | 20 | a = 42 21 | @@ -19,8 +30,19 @@ E26.py:22:5: E266 Too many leading `#` before block comment 23 | return 24 | #: E265:1:1 E266:2:1 | + = help: Remove leading `#` + +ℹ Safe fix +19 19 | ### This is a variable ### +20 20 | a = 42 +21 21 | +22 |- ### Of course it is unused + 22 |+ # Of course it is unused +23 23 | return +24 24 | #: E265:1:1 E266:2:1 +25 25 | ##if DEBUG: -E26.py:26:1: E266 Too many leading `#` before block comment +E26.py:26:1: E266 [*] Too many leading `#` before block comment | 24 | #: E265:1:1 E266:2:1 25 | ##if DEBUG: @@ -29,8 +51,19 @@ E26.py:26:1: E266 Too many leading `#` before block comment 27 | #: W291:1:42 28 | ######################################### | + = help: Remove leading `#` -E26.py:69:1: E266 Too many leading `#` before block comment +ℹ Safe fix +23 23 | return +24 24 | #: E265:1:1 E266:2:1 +25 25 | ##if DEBUG: +26 |-## logging.error() + 26 |+# logging.error() +27 27 | #: W291:1:42 +28 28 | ######################################### +29 29 | #: + +E26.py:69:1: E266 [*] Too many leading `#` before block comment | 68 | #: E265:5:1 69 | ### Means test is not done yet @@ -38,5 +71,37 @@ E26.py:69:1: E266 Too many leading `#` before block comment 70 | # E Means test is giving error (E) 71 | # F Means test is failing (F) | + = help: Remove leading `#` + +ℹ Safe fix +66 66 | a = 42 # (Two spaces) +67 67 | +68 68 | #: E265:5:1 +69 |-### Means test is not done yet + 69 |+# Means test is not done yet +70 70 | # E Means test is giving error (E) +71 71 | # F Means test is failing (F) +72 72 | # EF Means test is giving error and Failing + +E26.py:82:1: E266 [*] Too many leading `#` before block comment + | +80 | # We should strip the space, but preserve the hashes. +81 | #: E266:1:3 +82 | ## Foo + | ^^^^^^^ E266 +83 | +84 | a = 1 ## Foo + | + = help: Remove leading `#` + +ℹ Safe fix +79 79 | +80 80 | # We should strip the space, but preserve the hashes. +81 81 | #: E266:1:3 +82 |-## Foo + 82 |+# Foo +83 83 | +84 84 | a = 1 ## Foo +85 85 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E402_E402.ipynb.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E402_E402.ipynb.snap new file mode 100644 index 0000000000000..70562983d36e0 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E402_E402.ipynb.snap @@ -0,0 +1,29 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E402.ipynb:9:1: E402 Module level import not at top of cell + | + 7 | os.path + 8 | + 9 | import pathlib + | ^^^^^^^^^^^^^^ E402 +10 | +11 | import a + | + +E402.ipynb:22:1: E402 Module level import not at top of cell + | +20 | __some__magic = 1 +21 | +22 | import c + | ^^^^^^^^ E402 +23 | import ok + | + +E402.ipynb:30:1: E402 Module level import not at top of cell + | +30 | import no_ok + | ^^^^^^^^^^^^ E402 + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E402_E402.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E402_E402.py.snap index 8c15438eb55af..072290ae87cf6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E402_E402.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E402_E402.py.snap @@ -1,27 +1,57 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E402.py:24:1: E402 Module level import not at top of file +E402.py:25:1: E402 Module level import not at top of file | -22 | __some__magic = 1 -23 | -24 | import f +23 | sys.path.insert(0, "some/path") +24 | +25 | import f | ^^^^^^^^ E402 +26 | +27 | import matplotlib | -E402.py:34:1: E402 Module level import not at top of file +E402.py:27:1: E402 Module level import not at top of file | -32 | import g -33 | -34 | import h; import i +25 | import f +26 | +27 | import matplotlib + | ^^^^^^^^^^^^^^^^^ E402 +28 | +29 | matplotlib.use("Agg") + | + +E402.py:31:1: E402 Module level import not at top of file + | +29 | matplotlib.use("Agg") +30 | +31 | import g + | ^^^^^^^^ E402 +32 | +33 | __some__magic = 1 + | + +E402.py:35:1: E402 Module level import not at top of file + | +33 | __some__magic = 1 +34 | +35 | import h + | ^^^^^^^^ E402 + | + +E402.py:45:1: E402 Module level import not at top of file + | +43 | import j +44 | +45 | import k; import l | ^^^^^^^^ E402 | -E402.py:34:11: E402 Module level import not at top of file +E402.py:45:11: E402 Module level import not at top of file | -32 | import g -33 | -34 | import h; import i +43 | import j +44 | +45 | import k; import l | ^^^^^^^^ E402 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E703_E703.ipynb.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E703_E703.ipynb.snap new file mode 100644 index 0000000000000..068f245637b5c --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E703_E703.ipynb.snap @@ -0,0 +1,46 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E703.ipynb:5:2: E703 [*] Statement ends with an unnecessary semicolon + | +3 | x; +4 | # Only skip the last expression +5 | x; # E703 + | ^ E703 +6 | x; +7 | # Nested expressions isn't relevant + | + = help: Remove unnecessary semicolon + +ℹ Safe fix +2 2 | # Simple case +3 3 | x; +4 4 | # Only skip the last expression +5 |-x; # E703 + 5 |+x # E703 +6 6 | x; +7 7 | # Nested expressions isn't relevant +8 8 | if True: + +E703.ipynb:9:6: E703 [*] Statement ends with an unnecessary semicolon + | + 7 | # Nested expressions isn't relevant + 8 | if True: + 9 | x; + | ^ E703 +10 | # Semicolons with multiple expressions +11 | x; x; + | + = help: Remove unnecessary semicolon + +ℹ Safe fix +6 6 | x; +7 7 | # Nested expressions isn't relevant +8 8 | if True: +9 |- x; + 9 |+ x +10 10 | # Semicolons with multiple expressions +11 11 | x; x; +12 12 | # Comments, newlines and whitespace + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_0.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_0.py.snap index 98da5fff80c25..e4630487b7500 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_0.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_0.py.snap @@ -125,6 +125,8 @@ W605_0.py:45:12: W605 [*] Invalid escape sequence: `\_` 44 | 45 | regex = '\\\_' | ^^ W605 +46 | +47 | #: W605:1:7 | = help: Add backslash to escape sequence @@ -134,5 +136,23 @@ W605_0.py:45:12: W605 [*] Invalid escape sequence: `\_` 44 44 | 45 |-regex = '\\\_' 45 |+regex = '\\\\_' +46 46 | +47 47 | #: W605:1:7 +48 48 | u'foo\ bar' + +W605_0.py:48:6: W605 [*] Invalid escape sequence: `\ ` + | +47 | #: W605:1:7 +48 | u'foo\ bar' + | ^^ W605 + | + = help: Use a raw string literal + +ℹ Safe fix +45 45 | regex = '\\\_' +46 46 | +47 47 | #: W605:1:7 +48 |-u'foo\ bar' + 48 |+r'foo\ bar' diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_1.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_1.py.snap index 2fee83a5fee08..c47507e0ccc88 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_1.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_1.py.snap @@ -1,104 +1,227 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -W605_1.py:2:10: W605 [*] Invalid escape sequence: `\.` +W605_1.py:4:11: W605 [*] Invalid escape sequence: `\.` | -1 | #: W605:1:10 -2 | regex = '\.png$' - | ^^ W605 -3 | -4 | #: W605:2:1 +3 | #: W605:1:10 +4 | regex = f'\.png$' + | ^^ W605 +5 | +6 | #: W605:2:1 | = help: Use a raw string literal ℹ Safe fix -1 1 | #: W605:1:10 -2 |-regex = '\.png$' - 2 |+regex = r'\.png$' -3 3 | -4 4 | #: W605:2:1 -5 5 | regex = ''' - -W605_1.py:6:1: W605 [*] Invalid escape sequence: `\.` +1 1 | # Same as `W605_0.py` but using f-strings instead. +2 2 | +3 3 | #: W605:1:10 +4 |-regex = f'\.png$' + 4 |+regex = rf'\.png$' +5 5 | +6 6 | #: W605:2:1 +7 7 | regex = f''' + +W605_1.py:8:1: W605 [*] Invalid escape sequence: `\.` | -4 | #: W605:2:1 -5 | regex = ''' -6 | \.png$ +6 | #: W605:2:1 +7 | regex = f''' +8 | \.png$ | ^^ W605 -7 | ''' +9 | ''' | = help: Use a raw string literal ℹ Safe fix -2 2 | regex = '\.png$' -3 3 | -4 4 | #: W605:2:1 -5 |-regex = ''' - 5 |+regex = r''' -6 6 | \.png$ -7 7 | ''' -8 8 | - -W605_1.py:11:6: W605 [*] Invalid escape sequence: `\_` - | - 9 | #: W605:2:6 -10 | f( -11 | '\_' - | ^^ W605 -12 | ) +4 4 | regex = f'\.png$' +5 5 | +6 6 | #: W605:2:1 +7 |-regex = f''' + 7 |+regex = rf''' +8 8 | \.png$ +9 9 | ''' +10 10 | + +W605_1.py:13:7: W605 [*] Invalid escape sequence: `\_` + | +11 | #: W605:2:6 +12 | f( +13 | f'\_' + | ^^ W605 +14 | ) | = help: Use a raw string literal ℹ Safe fix -8 8 | -9 9 | #: W605:2:6 -10 10 | f( -11 |- '\_' - 11 |+ r'\_' -12 12 | ) -13 13 | -14 14 | #: W605:4:6 - -W605_1.py:18:6: W605 [*] Invalid escape sequence: `\_` - | -16 | multi-line -17 | literal -18 | with \_ somewhere +10 10 | +11 11 | #: W605:2:6 +12 12 | f( +13 |- f'\_' + 13 |+ rf'\_' +14 14 | ) +15 15 | +16 16 | #: W605:4:6 + +W605_1.py:20:6: W605 [*] Invalid escape sequence: `\_` + | +18 | multi-line +19 | literal +20 | with \_ somewhere | ^^ W605 -19 | in the middle -20 | """ +21 | in the middle +22 | """ | = help: Use a raw string literal ℹ Safe fix -12 12 | ) -13 13 | -14 14 | #: W605:4:6 -15 |-""" - 15 |+r""" -16 16 | multi-line -17 17 | literal -18 18 | with \_ somewhere - -W605_1.py:25:12: W605 [*] Invalid escape sequence: `\.` - | -23 | def f(): -24 | #: W605:1:11 -25 | return'\.png$' - | ^^ W605 -26 | -27 | #: Okay +14 14 | ) +15 15 | +16 16 | #: W605:4:6 +17 |-f""" + 17 |+rf""" +18 18 | multi-line +19 19 | literal +20 20 | with \_ somewhere + +W605_1.py:25:40: W605 [*] Invalid escape sequence: `\_` | - = help: Use a raw string literal +24 | #: W605:1:38 +25 | value = f'new line\nand invalid escape \_ here' + | ^^ W605 + | + = help: Add backslash to escape sequence ℹ Safe fix -22 22 | -23 23 | def f(): -24 24 | #: W605:1:11 -25 |- return'\.png$' - 25 |+ return r'\.png$' +22 22 | """ +23 23 | +24 24 | #: W605:1:38 +25 |-value = f'new line\nand invalid escape \_ here' + 25 |+value = f'new line\nand invalid escape \\_ here' 26 26 | -27 27 | #: Okay -28 28 | regex = r'\.png$' +27 27 | +28 28 | #: Okay + +W605_1.py:43:13: W605 [*] Invalid escape sequence: `\_` + | +41 | ''' # noqa +42 | +43 | regex = f'\\\_' + | ^^ W605 +44 | value = f'\{{1}}' +45 | value = f'\{1}' + | + = help: Add backslash to escape sequence + +ℹ Safe fix +40 40 | \w +41 41 | ''' # noqa +42 42 | +43 |-regex = f'\\\_' + 43 |+regex = f'\\\\_' +44 44 | value = f'\{{1}}' +45 45 | value = f'\{1}' +46 46 | value = f'{1:\}' + +W605_1.py:44:11: W605 [*] Invalid escape sequence: `\{` + | +43 | regex = f'\\\_' +44 | value = f'\{{1}}' + | ^^ W605 +45 | value = f'\{1}' +46 | value = f'{1:\}' + | + = help: Use a raw string literal + +ℹ Safe fix +41 41 | ''' # noqa +42 42 | +43 43 | regex = f'\\\_' +44 |-value = f'\{{1}}' + 44 |+value = rf'\{{1}}' +45 45 | value = f'\{1}' +46 46 | value = f'{1:\}' +47 47 | value = f"{f"\{1}"}" + +W605_1.py:45:11: W605 [*] Invalid escape sequence: `\{` + | +43 | regex = f'\\\_' +44 | value = f'\{{1}}' +45 | value = f'\{1}' + | ^^ W605 +46 | value = f'{1:\}' +47 | value = f"{f"\{1}"}" + | + = help: Use a raw string literal + +ℹ Safe fix +42 42 | +43 43 | regex = f'\\\_' +44 44 | value = f'\{{1}}' +45 |-value = f'\{1}' + 45 |+value = rf'\{1}' +46 46 | value = f'{1:\}' +47 47 | value = f"{f"\{1}"}" +48 48 | value = rf"{f"\{1}"}" + +W605_1.py:46:14: W605 [*] Invalid escape sequence: `\}` + | +44 | value = f'\{{1}}' +45 | value = f'\{1}' +46 | value = f'{1:\}' + | ^^ W605 +47 | value = f"{f"\{1}"}" +48 | value = rf"{f"\{1}"}" + | + = help: Use a raw string literal + +ℹ Safe fix +43 43 | regex = f'\\\_' +44 44 | value = f'\{{1}}' +45 45 | value = f'\{1}' +46 |-value = f'{1:\}' + 46 |+value = rf'{1:\}' +47 47 | value = f"{f"\{1}"}" +48 48 | value = rf"{f"\{1}"}" +49 49 | + +W605_1.py:47:14: W605 [*] Invalid escape sequence: `\{` + | +45 | value = f'\{1}' +46 | value = f'{1:\}' +47 | value = f"{f"\{1}"}" + | ^^ W605 +48 | value = rf"{f"\{1}"}" + | + = help: Use a raw string literal + +ℹ Safe fix +44 44 | value = f'\{{1}}' +45 45 | value = f'\{1}' +46 46 | value = f'{1:\}' +47 |-value = f"{f"\{1}"}" + 47 |+value = f"{rf"\{1}"}" +48 48 | value = rf"{f"\{1}"}" +49 49 | +50 50 | # Okay + +W605_1.py:48:15: W605 [*] Invalid escape sequence: `\{` + | +46 | value = f'{1:\}' +47 | value = f"{f"\{1}"}" +48 | value = rf"{f"\{1}"}" + | ^^ W605 +49 | +50 | # Okay + | + = help: Use a raw string literal + +ℹ Safe fix +45 45 | value = f'\{1}' +46 46 | value = f'{1:\}' +47 47 | value = f"{f"\{1}"}" +48 |-value = rf"{f"\{1}"}" + 48 |+value = rf"{rf"\{1}"}" +49 49 | +50 50 | # Okay +51 51 | value = rf'\{{1}}' diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_2.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_2.py.snap deleted file mode 100644 index 9f1016ae835e3..0000000000000 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_2.py.snap +++ /dev/null @@ -1,227 +0,0 @@ ---- -source: crates/ruff_linter/src/rules/pycodestyle/mod.rs ---- -W605_2.py:4:11: W605 [*] Invalid escape sequence: `\.` - | -3 | #: W605:1:10 -4 | regex = f'\.png$' - | ^^ W605 -5 | -6 | #: W605:2:1 - | - = help: Use a raw string literal - -ℹ Safe fix -1 1 | # Same as `W605_0.py` but using f-strings instead. -2 2 | -3 3 | #: W605:1:10 -4 |-regex = f'\.png$' - 4 |+regex = rf'\.png$' -5 5 | -6 6 | #: W605:2:1 -7 7 | regex = f''' - -W605_2.py:8:1: W605 [*] Invalid escape sequence: `\.` - | -6 | #: W605:2:1 -7 | regex = f''' -8 | \.png$ - | ^^ W605 -9 | ''' - | - = help: Use a raw string literal - -ℹ Safe fix -4 4 | regex = f'\.png$' -5 5 | -6 6 | #: W605:2:1 -7 |-regex = f''' - 7 |+regex = rf''' -8 8 | \.png$ -9 9 | ''' -10 10 | - -W605_2.py:13:7: W605 [*] Invalid escape sequence: `\_` - | -11 | #: W605:2:6 -12 | f( -13 | f'\_' - | ^^ W605 -14 | ) - | - = help: Use a raw string literal - -ℹ Safe fix -10 10 | -11 11 | #: W605:2:6 -12 12 | f( -13 |- f'\_' - 13 |+ rf'\_' -14 14 | ) -15 15 | -16 16 | #: W605:4:6 - -W605_2.py:20:6: W605 [*] Invalid escape sequence: `\_` - | -18 | multi-line -19 | literal -20 | with \_ somewhere - | ^^ W605 -21 | in the middle -22 | """ - | - = help: Use a raw string literal - -ℹ Safe fix -14 14 | ) -15 15 | -16 16 | #: W605:4:6 -17 |-f""" - 17 |+rf""" -18 18 | multi-line -19 19 | literal -20 20 | with \_ somewhere - -W605_2.py:25:40: W605 [*] Invalid escape sequence: `\_` - | -24 | #: W605:1:38 -25 | value = f'new line\nand invalid escape \_ here' - | ^^ W605 - | - = help: Add backslash to escape sequence - -ℹ Safe fix -22 22 | """ -23 23 | -24 24 | #: W605:1:38 -25 |-value = f'new line\nand invalid escape \_ here' - 25 |+value = f'new line\nand invalid escape \\_ here' -26 26 | -27 27 | -28 28 | #: Okay - -W605_2.py:43:13: W605 [*] Invalid escape sequence: `\_` - | -41 | ''' # noqa -42 | -43 | regex = f'\\\_' - | ^^ W605 -44 | value = f'\{{1}}' -45 | value = f'\{1}' - | - = help: Add backslash to escape sequence - -ℹ Safe fix -40 40 | \w -41 41 | ''' # noqa -42 42 | -43 |-regex = f'\\\_' - 43 |+regex = f'\\\\_' -44 44 | value = f'\{{1}}' -45 45 | value = f'\{1}' -46 46 | value = f'{1:\}' - -W605_2.py:44:11: W605 [*] Invalid escape sequence: `\{` - | -43 | regex = f'\\\_' -44 | value = f'\{{1}}' - | ^^ W605 -45 | value = f'\{1}' -46 | value = f'{1:\}' - | - = help: Use a raw string literal - -ℹ Safe fix -41 41 | ''' # noqa -42 42 | -43 43 | regex = f'\\\_' -44 |-value = f'\{{1}}' - 44 |+value = rf'\{{1}}' -45 45 | value = f'\{1}' -46 46 | value = f'{1:\}' -47 47 | value = f"{f"\{1}"}" - -W605_2.py:45:11: W605 [*] Invalid escape sequence: `\{` - | -43 | regex = f'\\\_' -44 | value = f'\{{1}}' -45 | value = f'\{1}' - | ^^ W605 -46 | value = f'{1:\}' -47 | value = f"{f"\{1}"}" - | - = help: Use a raw string literal - -ℹ Safe fix -42 42 | -43 43 | regex = f'\\\_' -44 44 | value = f'\{{1}}' -45 |-value = f'\{1}' - 45 |+value = rf'\{1}' -46 46 | value = f'{1:\}' -47 47 | value = f"{f"\{1}"}" -48 48 | value = rf"{f"\{1}"}" - -W605_2.py:46:14: W605 [*] Invalid escape sequence: `\}` - | -44 | value = f'\{{1}}' -45 | value = f'\{1}' -46 | value = f'{1:\}' - | ^^ W605 -47 | value = f"{f"\{1}"}" -48 | value = rf"{f"\{1}"}" - | - = help: Use a raw string literal - -ℹ Safe fix -43 43 | regex = f'\\\_' -44 44 | value = f'\{{1}}' -45 45 | value = f'\{1}' -46 |-value = f'{1:\}' - 46 |+value = rf'{1:\}' -47 47 | value = f"{f"\{1}"}" -48 48 | value = rf"{f"\{1}"}" -49 49 | - -W605_2.py:47:14: W605 [*] Invalid escape sequence: `\{` - | -45 | value = f'\{1}' -46 | value = f'{1:\}' -47 | value = f"{f"\{1}"}" - | ^^ W605 -48 | value = rf"{f"\{1}"}" - | - = help: Use a raw string literal - -ℹ Safe fix -44 44 | value = f'\{{1}}' -45 45 | value = f'\{1}' -46 46 | value = f'{1:\}' -47 |-value = f"{f"\{1}"}" - 47 |+value = f"{rf"\{1}"}" -48 48 | value = rf"{f"\{1}"}" -49 49 | -50 50 | # Okay - -W605_2.py:48:15: W605 [*] Invalid escape sequence: `\{` - | -46 | value = f'{1:\}' -47 | value = f"{f"\{1}"}" -48 | value = rf"{f"\{1}"}" - | ^^ W605 -49 | -50 | # Okay - | - = help: Use a raw string literal - -ℹ Safe fix -45 45 | value = f'\{1}' -46 46 | value = f'{1:\}' -47 47 | value = f"{f"\{1}"}" -48 |-value = rf"{f"\{1}"}" - 48 |+value = rf"{rf"\{1}"}" -49 49 | -50 50 | # Okay -51 51 | value = rf'\{{1}}' - - diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__preview__E402_E402.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__preview__E402_E402.py.snap new file mode 100644 index 0000000000000..7ec9e200b32e7 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__preview__E402_E402.py.snap @@ -0,0 +1,28 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E402.py:35:1: E402 Module level import not at top of file + | +33 | __some__magic = 1 +34 | +35 | import h + | ^^^^^^^^ E402 + | + +E402.py:45:1: E402 Module level import not at top of file + | +43 | import j +44 | +45 | import k; import l + | ^^^^^^^^ E402 + | + +E402.py:45:11: E402 Module level import not at top of file + | +43 | import j +44 | +45 | import k; import l + | ^^^^^^^^ E402 + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__shebang.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__shebang.snap index 63d5b9fefc8c5..fa3897bebc056 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__shebang.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__shebang.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -shebang.py:3:1: E265 Block comment should start with `# ` +shebang.py:3:1: E265 [*] Block comment should start with `# ` | 1 | #!/usr/bin/python 2 | # @@ -9,5 +9,13 @@ shebang.py:3:1: E265 Block comment should start with `# ` | ^^ E265 4 | #: | + = help: Format space + +ℹ Safe fix +1 1 | #!/usr/bin/python +2 2 | # +3 |-#! + 3 |+# ! +4 4 | #: diff --git a/crates/ruff_linter/src/rules/pydocstyle/helpers.rs b/crates/ruff_linter/src/rules/pydocstyle/helpers.rs index 355ff6ea16a8b..c165d34fa6815 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/helpers.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/helpers.rs @@ -10,8 +10,9 @@ pub(super) fn logical_line(content: &str) -> Option { // Find the first logical line. let mut logical_line = None; for (i, line) in content.universal_newlines().enumerate() { - if line.trim().is_empty() { - // Empty line. If this is the line _after_ the first logical line, stop. + let trimmed = line.trim(); + if trimmed.is_empty() || trimmed.chars().all(|c| matches!(c, '-' | '~' | '=' | '#')) { + // Empty line, or underline. If this is the line _after_ the first logical line, stop. if logical_line.is_some() { break; } diff --git a/crates/ruff_linter/src/rules/pydocstyle/mod.rs b/crates/ruff_linter/src/rules/pydocstyle/mod.rs index fad6a274a41af..5c08ee88dba7b 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/mod.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/mod.rs @@ -46,6 +46,7 @@ mod tests { #[test_case(Rule::NoBlankLineBeforeFunction, Path::new("D.py"))] #[test_case(Rule::BlankLinesBetweenHeaderAndContent, Path::new("sections.py"))] #[test_case(Rule::OverIndentation, Path::new("D.py"))] + #[test_case(Rule::OverIndentation, Path::new("D208.py"))] #[test_case(Rule::NoSignature, Path::new("D.py"))] #[test_case(Rule::SurroundingWhitespace, Path::new("D.py"))] #[test_case(Rule::DocstringStartsWithThis, Path::new("D.py"))] @@ -62,6 +63,7 @@ mod tests { #[test_case(Rule::UndocumentedPublicMethod, Path::new("D.py"))] #[test_case(Rule::UndocumentedPublicMethod, Path::new("setter.py"))] #[test_case(Rule::UndocumentedPublicModule, Path::new("D.py"))] + #[test_case(Rule::UndocumentedPublicModule, Path::new("D100.ipynb"))] #[test_case( Rule::UndocumentedPublicModule, Path::new("_unrelated/pkg/D100_pub.py") diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs index 497dd816e1367..c91565837f9ad 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs @@ -172,8 +172,9 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { let mut has_seen_tab = docstring.indentation.contains('\t'); let mut is_over_indented = true; let mut over_indented_lines = vec![]; - let mut over_indented_offset = TextSize::from(u32::MAX); + let mut over_indented_size = usize::MAX; + let docstring_indent_size = docstring.indentation.chars().count(); for i in 0..lines.len() { // First lines and continuations doesn't need any indentation. if i == 0 || lines[i - 1].ends_with('\\') { @@ -189,6 +190,7 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { } let line_indent = leading_space(line); + let line_indent_size = line_indent.chars().count(); // We only report tab indentation once, so only check if we haven't seen a tab // yet. @@ -197,9 +199,7 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { if checker.enabled(Rule::UnderIndentation) { // We report under-indentation on every line. This isn't great, but enables // fix. - if (i == lines.len() - 1 || !is_blank) - && line_indent.len() < docstring.indentation.len() - { + if (i == lines.len() - 1 || !is_blank) && line_indent_size < docstring_indent_size { let mut diagnostic = Diagnostic::new(UnderIndentation, TextRange::empty(line.start())); diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( @@ -217,14 +217,12 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { // until we've viewed all the lines, so for now, just track // the over-indentation status of every line. if i < lines.len() - 1 { - if line_indent.len() > docstring.indentation.len() { + if line_indent_size > docstring_indent_size { over_indented_lines.push(line); - // Track the _smallest_ offset we see - over_indented_offset = std::cmp::min( - line_indent.text_len() - docstring.indentation.text_len(), - over_indented_offset, - ); + // Track the _smallest_ offset we see, in terms of characters. + over_indented_size = + std::cmp::min(line_indent_size - docstring_indent_size, over_indented_size); } else { is_over_indented = false; } @@ -247,16 +245,36 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { let indent = clean_space(docstring.indentation); // We report over-indentation on every line. This isn't great, but - // enables fix. + // enables the fix capability. let mut diagnostic = Diagnostic::new(OverIndentation, TextRange::empty(line.start())); + let edit = if indent.is_empty() { + // Delete the entire indent. Edit::range_deletion(TextRange::at(line.start(), line_indent.text_len())) } else { - Edit::range_replacement( - indent.clone(), - TextRange::at(line.start(), indent.text_len() + over_indented_offset), - ) + // Convert the character count to an offset within the source. + // Example, where `[]` is a 2 byte non-breaking space: + // ``` + // def f(): + // """ Docstring header + // ^^^^ Real indentation is 4 chars + // docstring body, over-indented + // ^^^^^^ Over-indentation is 6 - 4 = 2 chars due to this line + // [] [] docstring body 2, further indented + // ^^^^^ We take these 4 chars/5 bytes to match the docstring ... + // ^^^ ... and these 2 chars/3 bytes to remove the `over_indented_size` ... + // ^^ ... but preserve this real indent + // ``` + let offset = checker + .locator() + .after(line.start()) + .chars() + .take(docstring.indentation.chars().count() + over_indented_size) + .map(TextLen::text_len) + .sum::(); + let range = TextRange::at(line.start(), offset); + Edit::range_replacement(indent, range) }; diagnostic.set_fix(Fix::safe_edit(edit)); checker.diagnostics.push(diagnostic); @@ -266,7 +284,8 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { // If the last line is over-indented... if let Some(last) = lines.last() { let line_indent = leading_space(last); - if line_indent.len() > docstring.indentation.len() { + let line_indent_size = line_indent.chars().count(); + if line_indent_size > docstring_indent_size { let mut diagnostic = Diagnostic::new(OverIndentation, TextRange::empty(last.start())); let indent = clean_space(docstring.indentation); diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs index 9288f3ff3731b..312bf596a4237 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs @@ -534,6 +534,9 @@ pub(crate) fn not_missing( kind: ModuleKind::Module, .. }) => { + if checker.source_type.is_ipynb() { + return true; + } if checker.enabled(Rule::UndocumentedPublicModule) { checker.diagnostics.push(Diagnostic::new( UndocumentedPublicModule, diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D100_D100.ipynb.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D100_D100.ipynb.snap new file mode 100644 index 0000000000000..724d6e7d20ae3 --- /dev/null +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D100_D100.ipynb.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/pydocstyle/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D.py.snap index caa57c1faa72d..5048d030c7dcd 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D.py.snap +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D.py.snap @@ -411,4 +411,22 @@ D.py:707:1: D208 [*] Docstring is over-indented 709 709 | 710 710 | +D.py:723:1: D208 [*] Docstring is over-indented + | +721 | """There's a non-breaking space (2-bytes) after 3 spaces (https://github.com/astral-sh/ruff/issues/9080). +722 | +723 |     Returns: + | D208 +724 | """ + | + = help: Remove over-indentation + +ℹ Safe fix +720 720 | def inconsistent_indent_byte_size(): +721 721 | """There's a non-breaking space (2-bytes) after 3 spaces (https://github.com/astral-sh/ruff/issues/9080). +722 722 | +723 |-     Returns: + 723 |+ Returns: +724 724 | """ + diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D208.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D208.py.snap new file mode 100644 index 0000000000000..517dc3802e1ec --- /dev/null +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D208.py.snap @@ -0,0 +1,81 @@ +--- +source: crates/ruff_linter/src/rules/pydocstyle/mod.rs +--- +D208.py:2:1: D208 [*] Docstring is over-indented + | +1 | """ +2 | Author + | D208 +3 | """ + | + = help: Remove over-indentation + +ℹ Safe fix +1 1 | """ +2 |- Author + 2 |+Author +3 3 | """ +4 4 | +5 5 | + +D208.py:8:1: D208 [*] Docstring is over-indented + | + 6 | class Platform: + 7 | """ Remove sampler + 8 | Args: + | D208 + 9 |     Returns: +10 | """ + | + = help: Remove over-indentation + +ℹ Safe fix +5 5 | +6 6 | class Platform: +7 7 | """ Remove sampler +8 |- Args: + 8 |+ Args: +9 9 |     Returns: +10 10 | """ +11 11 | + +D208.py:9:1: D208 [*] Docstring is over-indented + | + 7 | """ Remove sampler + 8 | Args: + 9 |     Returns: + | D208 +10 | """ + | + = help: Remove over-indentation + +ℹ Safe fix +6 6 | class Platform: +7 7 | """ Remove sampler +8 8 | Args: +9 |-     Returns: + 9 |+ Returns: +10 10 | """ +11 11 | +12 12 | + +D208.py:10:1: D208 [*] Docstring is over-indented + | + 8 | Args: + 9 |     Returns: +10 | """ + | D208 + | + = help: Remove over-indentation + +ℹ Safe fix +7 7 | """ Remove sampler +8 8 | Args: +9 9 |     Returns: +10 |- """ + 10 |+ """ +11 11 | +12 12 | +13 13 | def memory_test(): + + diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D213_D.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D213_D.py.snap index e0f3516e76c32..0253bc44cd427 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D213_D.py.snap +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D213_D.py.snap @@ -662,7 +662,7 @@ D.py:712:5: D213 [*] Multi-line docstring summary should start at the second lin 713 | | 714 | | This is not overindented 715 | | This is overindented, but since one line is not overindented this should not raise -716 | | And so is this, but it we should preserve the extra space on this line relative +716 | | And so is this, but it we should preserve the extra space on this line relative 717 | | """ | |_______^ D213 | @@ -679,4 +679,27 @@ D.py:712:5: D213 [*] Multi-line docstring summary should start at the second lin 714 715 | This is not overindented 715 716 | This is overindented, but since one line is not overindented this should not raise +D.py:721:5: D213 [*] Multi-line docstring summary should start at the second line + | +720 | def inconsistent_indent_byte_size(): +721 | """There's a non-breaking space (2-bytes) after 3 spaces (https://github.com/astral-sh/ruff/issues/9080). + | _____^ +722 | | +723 | |     Returns: +724 | | """ + | |_______^ D213 + | + = help: Insert line break and indentation after opening quotes + +ℹ Safe fix +718 718 | +719 719 | +720 720 | def inconsistent_indent_byte_size(): +721 |- """There's a non-breaking space (2-bytes) after 3 spaces (https://github.com/astral-sh/ruff/issues/9080). + 721 |+ """ + 722 |+ There's a non-breaking space (2-bytes) after 3 spaces (https://github.com/astral-sh/ruff/issues/9080). +722 723 | +723 724 |     Returns: +724 725 | """ + diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D400_D400.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D400_D400.py.snap index 6b522fd3e9172..f7a9059cce9bd 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D400_D400.py.snap +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D400_D400.py.snap @@ -247,4 +247,28 @@ D400.py:69:5: D400 [*] First line should end with a period 73 73 | 74 74 | +D400.py:97:5: D400 [*] First line should end with a period + | + 96 | def f(): + 97 | """ + | _____^ + 98 | | My example + 99 | | ========== +100 | | +101 | | My example explanation +102 | | """ + | |_______^ D400 + | + = help: Add period + +ℹ Unsafe fix +95 95 | +96 96 | def f(): +97 97 | """ +98 |- My example + 98 |+ My example. +99 99 | ========== +100 100 | +101 101 | My example explanation + diff --git a/crates/ruff_linter/src/rules/pyflakes/mod.rs b/crates/ruff_linter/src/rules/pyflakes/mod.rs index 9f105649915cd..435755ce9fe42 100644 --- a/crates/ruff_linter/src/rules/pyflakes/mod.rs +++ b/crates/ruff_linter/src/rules/pyflakes/mod.rs @@ -140,6 +140,7 @@ mod tests { #[test_case(Rule::UndefinedName, Path::new("F821_20.py"))] #[test_case(Rule::UndefinedName, Path::new("F821_21.py"))] #[test_case(Rule::UndefinedName, Path::new("F821_22.ipynb"))] + #[test_case(Rule::UndefinedName, Path::new("F821_23.py"))] #[test_case(Rule::UndefinedExport, Path::new("F822_0.py"))] #[test_case(Rule::UndefinedExport, Path::new("F822_1.py"))] #[test_case(Rule::UndefinedExport, Path::new("F822_2.py"))] diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/f_string_missing_placeholders.rs b/crates/ruff_linter/src/rules/pyflakes/rules/f_string_missing_placeholders.rs index 448959149e826..36263f332809e 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/f_string_missing_placeholders.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/f_string_missing_placeholders.rs @@ -1,7 +1,6 @@ use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::{self as ast, Expr, PySourceType}; -use ruff_python_parser::{lexer, AsMode, Tok}; +use ruff_python_ast as ast; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange, TextSize}; @@ -46,74 +45,37 @@ impl AlwaysFixableViolation for FStringMissingPlaceholders { } } -/// Return an iterator containing a two-element tuple for each f-string part -/// in the given [`ExprFString`] expression. -/// -/// The first element of the tuple is the f-string prefix range, and the second -/// element is the entire f-string range. It returns an iterator because of the -/// possibility of multiple f-strings implicitly concatenated together. -/// -/// For example, -/// -/// ```python -/// f"first" rf"second" -/// # ^ ^ (prefix range) -/// # ^^^^^^^^ ^^^^^^^^^^ (token range) -/// ``` -/// -/// would return `[(0..1, 0..8), (10..11, 9..19)]`. -/// -/// This function assumes that the given f-string expression is without any -/// placeholder expressions. -/// -/// [`ExprFString`]: `ruff_python_ast::ExprFString` -fn fstring_prefix_and_tok_range<'a>( - fstring: &'a ast::ExprFString, - locator: &'a Locator, - source_type: PySourceType, -) -> impl Iterator + 'a { - let contents = locator.slice(fstring); - let mut current_f_string_start = fstring.start(); - lexer::lex_starts_at(contents, source_type.as_mode(), fstring.start()) - .flatten() - .filter_map(move |(tok, range)| match tok { - Tok::FStringStart => { - current_f_string_start = range.start(); - None - } - Tok::FStringEnd => { - let first_char = - locator.slice(TextRange::at(current_f_string_start, TextSize::from(1))); - // f"..." => f_position = 0 - // fr"..." => f_position = 0 - // rf"..." => f_position = 1 - let f_position = u32::from(!(first_char == "f" || first_char == "F")); - Some(( - TextRange::at( - current_f_string_start + TextSize::from(f_position), - TextSize::from(1), - ), - TextRange::new(current_f_string_start, range.end()), - )) - } - _ => None, - }) -} - /// F541 -pub(crate) fn f_string_missing_placeholders(fstring: &ast::ExprFString, checker: &mut Checker) { - if !fstring.values.iter().any(Expr::is_formatted_value_expr) { - for (prefix_range, tok_range) in - fstring_prefix_and_tok_range(fstring, checker.locator(), checker.source_type) - { - let mut diagnostic = Diagnostic::new(FStringMissingPlaceholders, tok_range); - diagnostic.set_fix(convert_f_string_to_regular_string( - prefix_range, - tok_range, - checker.locator(), - )); - checker.diagnostics.push(diagnostic); - } +pub(crate) fn f_string_missing_placeholders(checker: &mut Checker, expr: &ast::ExprFString) { + if expr.value.f_strings().any(|f_string| { + f_string + .elements + .iter() + .any(ast::FStringElement::is_expression) + }) { + return; + } + + for f_string in expr.value.f_strings() { + let first_char = checker + .locator() + .slice(TextRange::at(f_string.start(), TextSize::new(1))); + // f"..." => f_position = 0 + // fr"..." => f_position = 0 + // rf"..." => f_position = 1 + let f_position = u32::from(!(first_char == "f" || first_char == "F")); + let prefix_range = TextRange::at( + f_string.start() + TextSize::new(f_position), + TextSize::new(1), + ); + + let mut diagnostic = Diagnostic::new(FStringMissingPlaceholders, f_string.range()); + diagnostic.set_fix(convert_f_string_to_regular_string( + prefix_range, + f_string.range(), + checker.locator(), + )); + checker.diagnostics.push(diagnostic); } } @@ -129,12 +91,12 @@ fn unescape_f_string(content: &str) -> String { /// Generate a [`Fix`] to rewrite an f-string as a regular string. fn convert_f_string_to_regular_string( prefix_range: TextRange, - tok_range: TextRange, + node_range: TextRange, locator: &Locator, ) -> Fix { // Extract the f-string body. let mut content = - unescape_f_string(locator.slice(TextRange::new(prefix_range.end(), tok_range.end()))); + unescape_f_string(locator.slice(TextRange::new(prefix_range.end(), node_range.end()))); // If the preceding character is equivalent to the quote character, insert a space to avoid a // syntax error. For example, when removing the `f` prefix in `""f""`, rewrite to `"" ""` @@ -151,6 +113,6 @@ fn convert_f_string_to_regular_string( Fix::safe_edit(Edit::replacement( content, prefix_range.start(), - tok_range.end(), + node_range.end(), )) } diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs b/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs index 8821f576ffbd0..e4545e139b79f 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs @@ -583,10 +583,10 @@ pub(crate) fn percent_format_extra_named_arguments( .enumerate() .filter_map(|(index, key)| match key { Some(Expr::StringLiteral(ast::ExprStringLiteral { value, .. })) => { - if summary.keywords.contains(value.as_str()) { + if summary.keywords.contains(value.to_str()) { None } else { - Some((index, value.as_str())) + Some((index, value.to_str())) } } _ => None, @@ -641,7 +641,7 @@ pub(crate) fn percent_format_missing_arguments( for key in keys.iter().flatten() { match key { Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { - keywords.insert(value); + keywords.insert(value.to_str()); } _ => { return; // Dynamic keys present @@ -652,7 +652,7 @@ pub(crate) fn percent_format_missing_arguments( let missing: Vec<&String> = summary .keywords .iter() - .filter(|k| !keywords.contains(k)) + .filter(|k| !keywords.contains(k.as_str())) .collect(); if !missing.is_empty() { diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/unused_variable.rs b/crates/ruff_linter/src/rules/pyflakes/rules/unused_variable.rs index f5eb694483617..e099c15f3110d 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/unused_variable.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/unused_variable.rs @@ -247,6 +247,14 @@ fn remove_unused_variable(binding: &Binding, checker: &Checker) -> Option { Some(Fix::unsafe_edit(edit).isolate(isolation)) }; } + } else { + let name = binding.name(checker.locator()); + let renamed = format!("_{name}"); + if checker.settings.dummy_variable_rgx.is_match(&renamed) { + let edit = Edit::range_replacement(renamed, binding.range()); + + return Some(Fix::unsafe_edit(edit).isolate(isolation)); + } } } diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_23.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_23.py.snap new file mode 100644 index 0000000000000..d0b409f39ee0b --- /dev/null +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_23.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/pyflakes/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_0.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_0.py.snap index 3fc06720a716c..7e1b2458bfa3f 100644 --- a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_0.py.snap +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_0.py.snap @@ -57,7 +57,7 @@ F841_0.py:20:5: F841 [*] Local variable `foo` is assigned to but never used 22 21 | 23 22 | bar = (1, 2) -F841_0.py:21:6: F841 Local variable `a` is assigned to but never used +F841_0.py:21:6: F841 [*] Local variable `a` is assigned to but never used | 19 | def f(): 20 | foo = (1, 2) @@ -68,7 +68,17 @@ F841_0.py:21:6: F841 Local variable `a` is assigned to but never used | = help: Remove assignment to unused variable `a` -F841_0.py:21:9: F841 Local variable `b` is assigned to but never used +ℹ Unsafe fix +18 18 | +19 19 | def f(): +20 20 | foo = (1, 2) +21 |- (a, b) = (1, 2) + 21 |+ (_a, b) = (1, 2) +22 22 | +23 23 | bar = (1, 2) +24 24 | (c, d) = bar + +F841_0.py:21:9: F841 [*] Local variable `b` is assigned to but never used | 19 | def f(): 20 | foo = (1, 2) @@ -79,6 +89,16 @@ F841_0.py:21:9: F841 Local variable `b` is assigned to but never used | = help: Remove assignment to unused variable `b` +ℹ Unsafe fix +18 18 | +19 19 | def f(): +20 20 | foo = (1, 2) +21 |- (a, b) = (1, 2) + 21 |+ (a, _b) = (1, 2) +22 22 | +23 23 | bar = (1, 2) +24 24 | (c, d) = bar + F841_0.py:26:14: F841 [*] Local variable `baz` is assigned to but never used | 24 | (c, d) = bar diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_1.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_1.py.snap index 7985de9913f88..9cb0b013fd00e 100644 --- a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_1.py.snap +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_1.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pyflakes/mod.rs --- -F841_1.py:6:5: F841 Local variable `x` is assigned to but never used +F841_1.py:6:5: F841 [*] Local variable `x` is assigned to but never used | 5 | def f(): 6 | x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed @@ -9,7 +9,17 @@ F841_1.py:6:5: F841 Local variable `x` is assigned to but never used | = help: Remove assignment to unused variable `x` -F841_1.py:6:8: F841 Local variable `y` is assigned to but never used +ℹ Unsafe fix +3 3 | +4 4 | +5 5 | def f(): +6 |- x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed + 6 |+ _x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed +7 7 | +8 8 | +9 9 | def f(): + +F841_1.py:6:8: F841 [*] Local variable `y` is assigned to but never used | 5 | def f(): 6 | x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed @@ -17,6 +27,16 @@ F841_1.py:6:8: F841 Local variable `y` is assigned to but never used | = help: Remove assignment to unused variable `y` +ℹ Unsafe fix +3 3 | +4 4 | +5 5 | def f(): +6 |- x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed + 6 |+ x, _y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed +7 7 | +8 8 | +9 9 | def f(): + F841_1.py:16:14: F841 [*] Local variable `coords` is assigned to but never used | 15 | def f(): @@ -53,7 +73,7 @@ F841_1.py:20:5: F841 [*] Local variable `coords` is assigned to but never used 22 22 | 23 23 | def f(): -F841_1.py:24:6: F841 Local variable `a` is assigned to but never used +F841_1.py:24:6: F841 [*] Local variable `a` is assigned to but never used | 23 | def f(): 24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything @@ -61,7 +81,14 @@ F841_1.py:24:6: F841 Local variable `a` is assigned to but never used | = help: Remove assignment to unused variable `a` -F841_1.py:24:9: F841 Local variable `b` is assigned to but never used +ℹ Unsafe fix +21 21 | +22 22 | +23 23 | def f(): +24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything + 24 |+ (_a, b) = (x, y) = 1, 2 # this triggers F841 on everything + +F841_1.py:24:9: F841 [*] Local variable `b` is assigned to but never used | 23 | def f(): 24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything @@ -69,7 +96,14 @@ F841_1.py:24:9: F841 Local variable `b` is assigned to but never used | = help: Remove assignment to unused variable `b` -F841_1.py:24:15: F841 Local variable `x` is assigned to but never used +ℹ Unsafe fix +21 21 | +22 22 | +23 23 | def f(): +24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything + 24 |+ (a, _b) = (x, y) = 1, 2 # this triggers F841 on everything + +F841_1.py:24:15: F841 [*] Local variable `x` is assigned to but never used | 23 | def f(): 24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything @@ -77,7 +111,14 @@ F841_1.py:24:15: F841 Local variable `x` is assigned to but never used | = help: Remove assignment to unused variable `x` -F841_1.py:24:18: F841 Local variable `y` is assigned to but never used +ℹ Unsafe fix +21 21 | +22 22 | +23 23 | def f(): +24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything + 24 |+ (a, b) = (_x, y) = 1, 2 # this triggers F841 on everything + +F841_1.py:24:18: F841 [*] Local variable `y` is assigned to but never used | 23 | def f(): 24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything @@ -85,4 +126,11 @@ F841_1.py:24:18: F841 Local variable `y` is assigned to but never used | = help: Remove assignment to unused variable `y` +ℹ Unsafe fix +21 21 | +22 22 | +23 23 | def f(): +24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything + 24 |+ (a, b) = (x, _y) = 1, 2 # this triggers F841 on everything + diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_3.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_3.py.snap index 9a29ab4098df2..8b60f4da8a24c 100644 --- a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_3.py.snap +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F841_F841_3.py.snap @@ -156,7 +156,7 @@ F841_3.py:27:46: F841 [*] Local variable `z3` is assigned to but never used 29 29 | 30 30 | -F841_3.py:32:6: F841 Local variable `x1` is assigned to but never used +F841_3.py:32:6: F841 [*] Local variable `x1` is assigned to but never used | 31 | def f(): 32 | (x1, y1) = (1, 2) @@ -166,7 +166,17 @@ F841_3.py:32:6: F841 Local variable `x1` is assigned to but never used | = help: Remove assignment to unused variable `x1` -F841_3.py:32:10: F841 Local variable `y1` is assigned to but never used +ℹ Unsafe fix +29 29 | +30 30 | +31 31 | def f(): +32 |- (x1, y1) = (1, 2) + 32 |+ (_x1, y1) = (1, 2) +33 33 | (x2, y2) = coords2 = (1, 2) +34 34 | coords3 = (x3, y3) = (1, 2) +35 35 | + +F841_3.py:32:10: F841 [*] Local variable `y1` is assigned to but never used | 31 | def f(): 32 | (x1, y1) = (1, 2) @@ -176,6 +186,16 @@ F841_3.py:32:10: F841 Local variable `y1` is assigned to but never used | = help: Remove assignment to unused variable `y1` +ℹ Unsafe fix +29 29 | +30 30 | +31 31 | def f(): +32 |- (x1, y1) = (1, 2) + 32 |+ (x1, _y1) = (1, 2) +33 33 | (x2, y2) = coords2 = (1, 2) +34 34 | coords3 = (x3, y3) = (1, 2) +35 35 | + F841_3.py:33:16: F841 [*] Local variable `coords2` is assigned to but never used | 31 | def f(): diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__preview__F841_F841_4.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__preview__F841_F841_4.py.snap index f781c31d82e2d..661343dd141da 100644 --- a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__preview__F841_F841_4.py.snap +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__preview__F841_F841_4.py.snap @@ -20,7 +20,7 @@ F841_4.py:12:5: F841 [*] Local variable `a` is assigned to but never used 14 14 | 15 15 | -F841_4.py:13:5: F841 Local variable `b` is assigned to but never used +F841_4.py:13:5: F841 [*] Local variable `b` is assigned to but never used | 11 | def bar(): 12 | a = foo() @@ -29,7 +29,17 @@ F841_4.py:13:5: F841 Local variable `b` is assigned to but never used | = help: Remove assignment to unused variable `b` -F841_4.py:13:8: F841 Local variable `c` is assigned to but never used +ℹ Unsafe fix +10 10 | +11 11 | def bar(): +12 12 | a = foo() +13 |- b, c = foo() + 13 |+ _b, c = foo() +14 14 | +15 15 | +16 16 | def baz(): + +F841_4.py:13:8: F841 [*] Local variable `c` is assigned to but never used | 11 | def bar(): 12 | a = foo() @@ -38,4 +48,14 @@ F841_4.py:13:8: F841 Local variable `c` is assigned to but never used | = help: Remove assignment to unused variable `c` +ℹ Unsafe fix +10 10 | +11 11 | def bar(): +12 12 | a = foo() +13 |- b, c = foo() + 13 |+ b, _c = foo() +14 14 | +15 15 | +16 16 | def baz(): + diff --git a/crates/ruff_linter/src/rules/pylint/helpers.rs b/crates/ruff_linter/src/rules/pylint/helpers.rs index aadd753b00f01..d68e639b59f56 100644 --- a/crates/ruff_linter/src/rules/pylint/helpers.rs +++ b/crates/ruff_linter/src/rules/pylint/helpers.rs @@ -1,9 +1,11 @@ use std::fmt; use ruff_python_ast as ast; -use ruff_python_ast::{Arguments, CmpOp, Expr}; +use ruff_python_ast::visitor::Visitor; +use ruff_python_ast::{visitor, Arguments, CmpOp, Expr, Stmt}; use ruff_python_semantic::analyze::function_type; use ruff_python_semantic::{ScopeKind, SemanticModel}; +use ruff_text_size::TextRange; use crate::settings::LinterSettings; @@ -11,8 +13,8 @@ use crate::settings::LinterSettings; pub(super) fn type_param_name(arguments: &Arguments) -> Option<&str> { // Handle both `TypeVar("T")` and `TypeVar(name="T")`. let name_param = arguments.find_argument("name", 0)?; - if let Expr::StringLiteral(ast::ExprStringLiteral { value: name, .. }) = &name_param { - Some(name) + if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = &name_param { + Some(value.to_str()) } else { None } @@ -82,3 +84,116 @@ impl fmt::Display for CmpOpExt { write!(f, "{representation}") } } + +/// Visitor to track reads from an iterable in a loop. +#[derive(Debug)] +pub(crate) struct SequenceIndexVisitor<'a> { + /// `letters`, given `for index, letter in enumerate(letters)`. + sequence_name: &'a str, + /// `index`, given `for index, letter in enumerate(letters)`. + index_name: &'a str, + /// `letter`, given `for index, letter in enumerate(letters)`. + value_name: &'a str, + /// The ranges of any `letters[index]` accesses. + accesses: Vec, + /// Whether any of the variables have been modified. + modified: bool, +} + +impl<'a> SequenceIndexVisitor<'a> { + pub(crate) fn new(sequence_name: &'a str, index_name: &'a str, value_name: &'a str) -> Self { + Self { + sequence_name, + index_name, + value_name, + accesses: Vec::new(), + modified: false, + } + } + + pub(crate) fn into_accesses(self) -> Vec { + self.accesses + } +} + +impl SequenceIndexVisitor<'_> { + fn is_assignment(&self, expr: &Expr) -> bool { + // If we see the sequence, a subscript, or the index being modified, we'll stop emitting + // diagnostics. + match expr { + Expr::Name(ast::ExprName { id, .. }) => { + id == self.sequence_name || id == self.index_name || id == self.value_name + } + Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => { + let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else { + return false; + }; + if id == self.sequence_name { + let Expr::Name(ast::ExprName { id, .. }) = slice.as_ref() else { + return false; + }; + if id == self.index_name { + return true; + } + } + false + } + _ => false, + } + } +} + +impl<'a> Visitor<'_> for SequenceIndexVisitor<'a> { + fn visit_stmt(&mut self, stmt: &Stmt) { + if self.modified { + return; + } + match stmt { + Stmt::Assign(ast::StmtAssign { targets, value, .. }) => { + self.modified = targets.iter().any(|target| self.is_assignment(target)); + self.visit_expr(value); + } + Stmt::AnnAssign(ast::StmtAnnAssign { target, value, .. }) => { + if let Some(value) = value { + self.modified = self.is_assignment(target); + self.visit_expr(value); + } + } + Stmt::AugAssign(ast::StmtAugAssign { target, value, .. }) => { + self.modified = self.is_assignment(target); + self.visit_expr(value); + } + Stmt::Delete(ast::StmtDelete { targets, .. }) => { + self.modified = targets.iter().any(|target| self.is_assignment(target)); + } + _ => visitor::walk_stmt(self, stmt), + } + } + + fn visit_expr(&mut self, expr: &Expr) { + if self.modified { + return; + } + match expr { + Expr::Subscript(ast::ExprSubscript { + value, + slice, + range, + .. + }) => { + let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else { + return; + }; + if id == self.sequence_name { + let Expr::Name(ast::ExprName { id, .. }) = slice.as_ref() else { + return; + }; + if id == self.index_name { + self.accesses.push(*range); + } + } + } + _ => visitor::walk_expr(self, expr), + } + } +} diff --git a/crates/ruff_linter/src/rules/pylint/mod.rs b/crates/ruff_linter/src/rules/pylint/mod.rs index 2c4e28ca363e6..3933e07bf9e02 100644 --- a/crates/ruff_linter/src/rules/pylint/mod.rs +++ b/crates/ruff_linter/src/rules/pylint/mod.rs @@ -9,6 +9,7 @@ mod tests { use anyhow::Result; use regex::Regex; + use rustc_hash::FxHashSet; use test_case::test_case; use crate::assert_messages; @@ -93,6 +94,7 @@ mod tests { #[test_case(Rule::RedefinedLoopName, Path::new("redefined_loop_name.py"))] #[test_case(Rule::ReturnInInit, Path::new("return_in_init.py"))] #[test_case(Rule::TooManyArguments, Path::new("too_many_arguments.py"))] + #[test_case(Rule::TooManyPositional, Path::new("too_many_positional.py"))] #[test_case(Rule::TooManyBranches, Path::new("too_many_branches.py"))] #[test_case( Rule::TooManyReturnStatements, @@ -153,11 +155,29 @@ mod tests { Rule::RepeatedKeywordArgument, Path::new("repeated_keyword_argument.py") )] + #[test_case( + Rule::UnnecessaryListIndexLookup, + Path::new("unnecessary_list_index_lookup.py") + )] + #[test_case(Rule::NoClassmethodDecorator, Path::new("no_method_decorator.py"))] + #[test_case(Rule::NoStaticmethodDecorator, Path::new("no_method_decorator.py"))] + #[test_case( + Rule::UnnecessaryDictIndexLookup, + Path::new("unnecessary_dict_index_lookup.py") + )] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( Path::new("pylint").join(path).as_path(), - &LinterSettings::for_rule(rule_code), + &LinterSettings { + pylint: pylint::settings::Settings { + allow_dunder_method_names: FxHashSet::from_iter([ + "__special_custom_magic__".to_string() + ]), + ..pylint::settings::Settings::default() + }, + ..LinterSettings::for_rule(rule_code) + }, )?; assert_messages!(snapshot, diagnostics); Ok(()) @@ -230,6 +250,22 @@ mod tests { Ok(()) } + #[test] + fn max_positional_args() -> Result<()> { + let diagnostics = test_path( + Path::new("pylint/too_many_positional_params.py"), + &LinterSettings { + pylint: pylint::settings::Settings { + max_positional_args: 4, + ..pylint::settings::Settings::default() + }, + ..LinterSettings::for_rule(Rule::TooManyPositional) + }, + )?; + assert_messages!(diagnostics); + Ok(()) + } + #[test] fn max_branches() -> Result<()> { let diagnostics = test_path( @@ -309,4 +345,15 @@ mod tests { assert_messages!(diagnostics); Ok(()) } + + #[test] + fn unspecified_encoding_python39_or_lower() -> Result<()> { + let diagnostics = test_path( + Path::new("pylint/unspecified_encoding.py"), + &LinterSettings::for_rule(Rule::UnspecifiedEncoding) + .with_target_version(PythonVersion::Py39), + )?; + assert_messages!(diagnostics); + Ok(()) + } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/assert_on_string_literal.rs b/crates/ruff_linter/src/rules/pylint/rules/assert_on_string_literal.rs index f32bbd98946db..5f0801731f695 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/assert_on_string_literal.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/assert_on_string_literal.rs @@ -69,27 +69,36 @@ pub(crate) fn assert_on_string_literal(checker: &mut Checker, test: &Expr) { test.range(), )); } - Expr::FString(ast::ExprFString { values, .. }) => { + Expr::FString(ast::ExprFString { value, .. }) => { + let kind = if value.iter().all(|f_string_part| match f_string_part { + ast::FStringPart::Literal(literal) => literal.is_empty(), + ast::FStringPart::FString(f_string) => { + f_string.elements.iter().all(|element| match element { + ast::FStringElement::Literal(ast::FStringLiteralElement { + value, .. + }) => value.is_empty(), + ast::FStringElement::Expression(_) => false, + }) + } + }) { + Kind::Empty + } else if value.iter().any(|f_string_part| match f_string_part { + ast::FStringPart::Literal(literal) => !literal.is_empty(), + ast::FStringPart::FString(f_string) => { + f_string.elements.iter().any(|element| match element { + ast::FStringElement::Literal(ast::FStringLiteralElement { + value, .. + }) => !value.is_empty(), + ast::FStringElement::Expression(_) => false, + }) + } + }) { + Kind::NonEmpty + } else { + Kind::Unknown + }; checker.diagnostics.push(Diagnostic::new( - AssertOnStringLiteral { - kind: if values.iter().all(|value| match value { - Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { - value.is_empty() - } - _ => false, - }) { - Kind::Empty - } else if values.iter().any(|value| match value { - Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { - !value.is_empty() - } - _ => false, - }) { - Kind::NonEmpty - } else { - Kind::Unknown - }, - }, + AssertOnStringLiteral { kind }, test.range(), )); } diff --git a/crates/ruff_linter/src/rules/pylint/rules/bad_dunder_method_name.rs b/crates/ruff_linter/src/rules/pylint/rules/bad_dunder_method_name.rs index 752c3a67351ee..87c14839cfc69 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/bad_dunder_method_name.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/bad_dunder_method_name.rs @@ -22,6 +22,9 @@ use crate::checkers::ast::Checker; /// one underscore (e.g., `_str_`), but ignores known dunder methods (like /// `__init__`), as well as methods that are marked with `@override`. /// +/// Additional dunder methods names can be allowed via the +/// [`pylint.allow-dunder-method-names`] setting. +/// /// ## Example /// ```python /// class Foo: @@ -35,6 +38,9 @@ use crate::checkers::ast::Checker; /// def __init__(self): /// ... /// ``` +/// +/// ## Options +/// - `pylint.allow-dunder-method-names` #[violation] pub struct BadDunderMethodName { name: String, @@ -54,7 +60,14 @@ pub(crate) fn bad_dunder_method_name(checker: &mut Checker, class_body: &[Stmt]) .iter() .filter_map(ruff_python_ast::Stmt::as_function_def_stmt) .filter(|method| { - if is_known_dunder_method(&method.name) || matches!(method.name.as_str(), "_") { + if is_known_dunder_method(&method.name) + || checker + .settings + .pylint + .allow_dunder_method_names + .contains(method.name.as_str()) + || matches!(method.name.as_str(), "_") + { return false; } method.name.starts_with('_') && method.name.ends_with('_') diff --git a/crates/ruff_linter/src/rules/pylint/rules/bad_open_mode.rs b/crates/ruff_linter/src/rules/pylint/rules/bad_open_mode.rs index 0750af43b59a0..a5e7f5f325751 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/bad_open_mode.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/bad_open_mode.rs @@ -154,7 +154,7 @@ impl TryFrom for OpenMode { } /// Returns `true` if the open mode is valid. -fn is_valid_mode(mode: &str) -> bool { +fn is_valid_mode(mode: &ast::StringLiteralValue) -> bool { // Flag duplicates and invalid characters. let mut flags = OpenMode::empty(); for char in mode.chars() { diff --git a/crates/ruff_linter/src/rules/pylint/rules/bad_str_strip_call.rs b/crates/ruff_linter/src/rules/pylint/rules/bad_str_strip_call.rs index 36fc831d59c8b..dafa3b0c4f98f 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/bad_str_strip_call.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/bad_str_strip_call.rs @@ -122,7 +122,7 @@ impl fmt::Display for RemovalKind { /// Return `true` if a string contains duplicate characters, taking into account /// escapes. -fn has_duplicates(s: &str) -> bool { +fn has_duplicates(s: &ast::StringLiteralValue) -> bool { let mut escaped = false; let mut seen = FxHashSet::default(); for ch in s.chars() { diff --git a/crates/ruff_linter/src/rules/pylint/rules/bad_string_format_type.rs b/crates/ruff_linter/src/rules/pylint/rules/bad_string_format_type.rs index 4d62c785de583..b41e4f59d9249 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/bad_string_format_type.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/bad_string_format_type.rs @@ -124,8 +124,8 @@ fn equivalent(format: &CFormatSpec, value: &Expr) -> bool { ResolvedPythonType::Atom(atom) => { // Special case where `%c` allows single character strings to be formatted if format.format_char == 'c' { - if let Expr::StringLiteral(string) = value { - let mut chars = string.chars(); + if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = value { + let mut chars = value.chars(); if chars.next().is_some() && chars.next().is_none() { return true; } @@ -201,7 +201,7 @@ fn is_valid_dict( value: mapping_key, .. }) = key { - let Some(format) = formats_hash.get(mapping_key.as_str()) else { + let Some(format) = formats_hash.get(mapping_key.to_str()) else { return true; }; if !equivalent(format, value) { diff --git a/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs b/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs index ce02b12fff433..8aa58e70e8026 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs @@ -21,6 +21,14 @@ use crate::rules::pylint::helpers::CmpOpExt; /// foo == foo /// ``` /// +/// In some cases, self-comparisons are used to determine whether a float is +/// NaN. Instead, prefer `math.isnan`: +/// ```python +/// import math +/// +/// math.isnan(foo) +/// ``` +/// /// ## References /// - [Python documentation: Comparisons](https://docs.python.org/3/reference/expressions.html#comparisons) #[violation] diff --git a/crates/ruff_linter/src/rules/pylint/rules/logging.rs b/crates/ruff_linter/src/rules/pylint/rules/logging.rs index 0765b5a4c7337..823bf8bdfcb7e 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/logging.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/logging.rs @@ -134,7 +134,7 @@ pub(crate) fn logging_call(checker: &mut Checker, call: &ast::ExprCall) { return; }; - let Ok(summary) = CFormatSummary::try_from(value.as_str()) else { + let Ok(summary) = CFormatSummary::try_from(value.to_str()) else { return; }; diff --git a/crates/ruff_linter/src/rules/pylint/rules/magic_value_comparison.rs b/crates/ruff_linter/src/rules/pylint/rules/magic_value_comparison.rs index c47f91ff62a2f..ad1309b317d98 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/magic_value_comparison.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/magic_value_comparison.rs @@ -83,7 +83,7 @@ fn is_magic_value(literal_expr: LiteralExpressionRef, allowed_types: &[ConstantT | LiteralExpressionRef::EllipsisLiteral(_) => false, // Special-case some common string and integer types. LiteralExpressionRef::StringLiteral(ast::ExprStringLiteral { value, .. }) => { - !matches!(value.as_str(), "" | "__main__") + !matches!(value.to_str(), "" | "__main__") } LiteralExpressionRef::NumberLiteral(ast::ExprNumberLiteral { value, .. }) => match value { ast::Number::Int(value) => !matches!(*value, Int::ZERO | Int::ONE), diff --git a/crates/ruff_linter/src/rules/pylint/rules/mod.rs b/crates/ruff_linter/src/rules/pylint/rules/mod.rs index b130d36260182..aaedd82e2f790 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/mod.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/mod.rs @@ -35,6 +35,7 @@ pub(crate) use manual_import_from::*; pub(crate) use misplaced_bare_raise::*; pub(crate) use named_expr_without_context::*; pub(crate) use nested_min_max::*; +pub(crate) use no_method_decorator::*; pub(crate) use no_self_use::*; pub(crate) use non_ascii_module_import::*; pub(crate) use non_ascii_name::*; @@ -54,6 +55,7 @@ pub(crate) use sys_exit_alias::*; pub(crate) use too_many_arguments::*; pub(crate) use too_many_boolean_expressions::*; pub(crate) use too_many_branches::*; +pub(crate) use too_many_positional::*; pub(crate) use too_many_public_methods::*; pub(crate) use too_many_return_statements::*; pub(crate) use too_many_statements::*; @@ -61,8 +63,10 @@ pub(crate) use type_bivariance::*; pub(crate) use type_name_incorrect_variance::*; pub(crate) use type_param_name_mismatch::*; pub(crate) use unexpected_special_method_signature::*; +pub(crate) use unnecessary_dict_index_lookup::*; pub(crate) use unnecessary_direct_lambda_call::*; pub(crate) use unnecessary_lambda::*; +pub(crate) use unnecessary_list_index_lookup::*; pub(crate) use unspecified_encoding::*; pub(crate) use useless_else_on_loop::*; pub(crate) use useless_import_alias::*; @@ -108,6 +112,7 @@ mod manual_import_from; mod misplaced_bare_raise; mod named_expr_without_context; mod nested_min_max; +mod no_method_decorator; mod no_self_use; mod non_ascii_module_import; mod non_ascii_name; @@ -127,6 +132,7 @@ mod sys_exit_alias; mod too_many_arguments; mod too_many_boolean_expressions; mod too_many_branches; +mod too_many_positional; mod too_many_public_methods; mod too_many_return_statements; mod too_many_statements; @@ -134,8 +140,10 @@ mod type_bivariance; mod type_name_incorrect_variance; mod type_param_name_mismatch; mod unexpected_special_method_signature; +mod unnecessary_dict_index_lookup; mod unnecessary_direct_lambda_call; mod unnecessary_lambda; +mod unnecessary_list_index_lookup; mod unspecified_encoding; mod useless_else_on_loop; mod useless_import_alias; diff --git a/crates/ruff_linter/src/rules/pylint/rules/no_method_decorator.rs b/crates/ruff_linter/src/rules/pylint/rules/no_method_decorator.rs new file mode 100644 index 0000000000000..60439119fd703 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/no_method_decorator.rs @@ -0,0 +1,202 @@ +use std::collections::HashMap; + +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, DiagnosticKind, Edit, Fix}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr, Stmt}; +use ruff_python_trivia::indentation_at_offset; +use ruff_text_size::{Ranged, TextRange, TextSize}; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for the use of a classmethod being made without the decorator. +/// +/// ## Why is this bad? +/// When it comes to consistency and readability, it's preferred to use the decorator. +/// +/// ## Example +/// ```python +/// class Foo: +/// def bar(cls): +/// ... +/// +/// bar = classmethod(bar) +/// ``` +/// +/// Use instead: +/// ```python +/// class Foo: +/// @classmethod +/// def bar(cls): +/// ... +/// ``` +#[violation] +pub struct NoClassmethodDecorator; + +impl AlwaysFixableViolation for NoClassmethodDecorator { + #[derive_message_formats] + fn message(&self) -> String { + format!("Class method defined without decorator") + } + + fn fix_title(&self) -> String { + format!("Add @classmethod decorator") + } +} + +/// ## What it does +/// Checks for the use of a staticmethod being made without the decorator. +/// +/// ## Why is this bad? +/// When it comes to consistency and readability, it's preferred to use the decorator. +/// +/// ## Example +/// ```python +/// class Foo: +/// def bar(arg1, arg2): +/// ... +/// +/// bar = staticmethod(bar) +/// ``` +/// +/// Use instead: +/// ```python +/// class Foo: +/// @staticmethod +/// def bar(arg1, arg2): +/// ... +/// ``` +#[violation] +pub struct NoStaticmethodDecorator; + +impl AlwaysFixableViolation for NoStaticmethodDecorator { + #[derive_message_formats] + fn message(&self) -> String { + format!("Static method defined without decorator") + } + + fn fix_title(&self) -> String { + format!("Add @staticmethod decorator") + } +} + +enum MethodType { + Classmethod, + Staticmethod, +} + +/// PLR0202 +pub(crate) fn no_classmethod_decorator(checker: &mut Checker, class_def: &ast::StmtClassDef) { + get_undecorated_methods(checker, class_def, &MethodType::Classmethod); +} + +/// PLR0203 +pub(crate) fn no_staticmethod_decorator(checker: &mut Checker, class_def: &ast::StmtClassDef) { + get_undecorated_methods(checker, class_def, &MethodType::Staticmethod); +} + +fn get_undecorated_methods( + checker: &mut Checker, + class_def: &ast::StmtClassDef, + method_type: &MethodType, +) { + let mut explicit_decorator_calls: HashMap = HashMap::default(); + + let (method_name, diagnostic_type): (&str, DiagnosticKind) = match method_type { + MethodType::Classmethod => ("classmethod", NoClassmethodDecorator.into()), + MethodType::Staticmethod => ("staticmethod", NoStaticmethodDecorator.into()), + }; + + // gather all explicit *method calls + for stmt in &class_def.body { + if let Stmt::Assign(ast::StmtAssign { targets, value, .. }) = stmt { + if let Expr::Call(ast::ExprCall { + func, arguments, .. + }) = value.as_ref() + { + if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() { + if id == method_name && checker.semantic().is_builtin(method_name) { + if arguments.args.len() != 1 { + continue; + } + + if targets.len() != 1 { + continue; + } + + let target_name = match targets.first() { + Some(Expr::Name(ast::ExprName { id, .. })) => id.to_string(), + _ => continue, + }; + + if let Expr::Name(ast::ExprName { id, .. }) = &arguments.args[0] { + if target_name == *id { + explicit_decorator_calls.insert(id.clone(), stmt.range()); + } + }; + } + } + } + }; + } + + if explicit_decorator_calls.is_empty() { + return; + }; + + for stmt in &class_def.body { + if let Stmt::FunctionDef(ast::StmtFunctionDef { + name, + decorator_list, + .. + }) = stmt + { + if !explicit_decorator_calls.contains_key(name.as_str()) { + continue; + }; + + // if we find the decorator we're looking for, skip + if decorator_list.iter().any(|decorator| { + if let Expr::Name(ast::ExprName { id, .. }) = &decorator.expression { + if id == method_name && checker.semantic().is_builtin(method_name) { + return true; + } + } + + false + }) { + continue; + } + + let mut diagnostic = Diagnostic::new( + diagnostic_type.clone(), + TextRange::new(stmt.range().start(), stmt.range().start()), + ); + + let indentation = indentation_at_offset(stmt.range().start(), checker.locator()); + + match indentation { + Some(indentation) => { + let range = &explicit_decorator_calls[name.as_str()]; + + // SAFETY: Ruff only supports formatting files <= 4GB + #[allow(clippy::cast_possible_truncation)] + diagnostic.set_fix(Fix::safe_edits( + Edit::insertion( + format!("@{method_name}\n{indentation}"), + stmt.range().start(), + ), + [Edit::deletion( + range.start() - TextSize::from(indentation.len() as u32), + range.end(), + )], + )); + checker.diagnostics.push(diagnostic); + } + None => { + continue; + } + }; + }; + } +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/repeated_keyword_argument.rs b/crates/ruff_linter/src/rules/pylint/rules/repeated_keyword_argument.rs index 42e896054028b..b65f8fd6b4ac9 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/repeated_keyword_argument.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/repeated_keyword_argument.rs @@ -60,7 +60,7 @@ pub(crate) fn repeated_keyword_argument(checker: &mut Checker, call: &ExprCall) // Ex) `func(**{"a": 1, "a": 2})` for key in keys.iter().flatten() { if let Expr::StringLiteral(ExprStringLiteral { value, .. }) = key { - if !seen.insert(value) { + if !seen.insert(value.to_str()) { checker.diagnostics.push(Diagnostic::new( RepeatedKeywordArgument { duplicate_keyword: value.to_string(), diff --git a/crates/ruff_linter/src/rules/pylint/rules/self_assigning_variable.rs b/crates/ruff_linter/src/rules/pylint/rules/self_assigning_variable.rs index a30b6294acc43..68875a9eb57c2 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/self_assigning_variable.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/self_assigning_variable.rs @@ -1,3 +1,4 @@ +use itertools::Itertools; use ruff_python_ast::{self as ast, Expr}; use ruff_diagnostics::{Diagnostic, Violation}; @@ -36,30 +37,28 @@ impl Violation for SelfAssigningVariable { } /// PLW0127 -pub(crate) fn self_assigning_variable(checker: &mut Checker, target: &Expr, value: &Expr) { - fn inner(left: &Expr, right: &Expr, diagnostics: &mut Vec) { - match (left, right) { - ( - Expr::Tuple(ast::ExprTuple { elts: lhs_elts, .. }), - Expr::Tuple(ast::ExprTuple { elts: rhs_elts, .. }), - ) if lhs_elts.len() == rhs_elts.len() => lhs_elts - .iter() - .zip(rhs_elts.iter()) - .for_each(|(lhs, rhs)| inner(lhs, rhs, diagnostics)), - ( - Expr::Name(ast::ExprName { id: lhs_name, .. }), - Expr::Name(ast::ExprName { id: rhs_name, .. }), - ) if lhs_name == rhs_name => { - diagnostics.push(Diagnostic::new( - SelfAssigningVariable { - name: lhs_name.to_string(), - }, - left.range(), - )); - } - _ => {} - } +pub(crate) fn self_assignment(checker: &mut Checker, assign: &ast::StmtAssign) { + // Assignments in class bodies are attributes (e.g., `x = x` assigns `x` to `self.x`, and thus + // is not a self-assignment). + if checker.semantic().current_scope().kind.is_class() { + return; + } + + for (left, right) in assign + .targets + .iter() + .chain(std::iter::once(assign.value.as_ref())) + .tuple_combinations() + { + visit_assignments(left, right, &mut checker.diagnostics); } +} + +/// PLW0127 +pub(crate) fn self_annotated_assignment(checker: &mut Checker, assign: &ast::StmtAnnAssign) { + let Some(value) = assign.value.as_ref() else { + return; + }; // Assignments in class bodies are attributes (e.g., `x = x` assigns `x` to `self.x`, and thus // is not a self-assignment). @@ -67,5 +66,29 @@ pub(crate) fn self_assigning_variable(checker: &mut Checker, target: &Expr, valu return; } - inner(target, value, &mut checker.diagnostics); + visit_assignments(&assign.target, value, &mut checker.diagnostics); +} + +fn visit_assignments(left: &Expr, right: &Expr, diagnostics: &mut Vec) { + match (left, right) { + ( + Expr::Tuple(ast::ExprTuple { elts: lhs_elts, .. }), + Expr::Tuple(ast::ExprTuple { elts: rhs_elts, .. }), + ) if lhs_elts.len() == rhs_elts.len() => lhs_elts + .iter() + .zip(rhs_elts.iter()) + .for_each(|(lhs, rhs)| visit_assignments(lhs, rhs, diagnostics)), + ( + Expr::Name(ast::ExprName { id: lhs_name, .. }), + Expr::Name(ast::ExprName { id: rhs_name, .. }), + ) if lhs_name == rhs_name => { + diagnostics.push(Diagnostic::new( + SelfAssigningVariable { + name: lhs_name.to_string(), + }, + left.range(), + )); + } + _ => {} + } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/subprocess_run_without_check.rs b/crates/ruff_linter/src/rules/pylint/rules/subprocess_run_without_check.rs index 4758de8d017b9..67b494d6bb700 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/subprocess_run_without_check.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/subprocess_run_without_check.rs @@ -1,9 +1,10 @@ -use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast as ast; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; +use crate::fix::edits::add_argument; /// ## What it does /// Checks for uses of `subprocess.run` without an explicit `check` argument. @@ -36,16 +37,25 @@ use crate::checkers::ast::Checker; /// subprocess.run(["ls", "nonexistent"], check=False) # Explicitly no check. /// ``` /// +/// ## Fix safety +/// This rule's fix is marked as unsafe for function calls that contain +/// `**kwargs`, as adding a `check` keyword argument to such a call may lead +/// to a duplicate keyword argument error. +/// /// ## References /// - [Python documentation: `subprocess.run`](https://docs.python.org/3/library/subprocess.html#subprocess.run) #[violation] pub struct SubprocessRunWithoutCheck; -impl Violation for SubprocessRunWithoutCheck { +impl AlwaysFixableViolation for SubprocessRunWithoutCheck { #[derive_message_formats] fn message(&self) -> String { format!("`subprocess.run` without explicit `check` argument") } + + fn fix_title(&self) -> String { + "Add explicit `check=False`".to_string() + } } /// PLW1510 @@ -56,10 +66,27 @@ pub(crate) fn subprocess_run_without_check(checker: &mut Checker, call: &ast::Ex .is_some_and(|call_path| matches!(call_path.as_slice(), ["subprocess", "run"])) { if call.arguments.find_keyword("check").is_none() { - checker.diagnostics.push(Diagnostic::new( - SubprocessRunWithoutCheck, - call.func.range(), + let mut diagnostic = Diagnostic::new(SubprocessRunWithoutCheck, call.func.range()); + diagnostic.set_fix(Fix::applicable_edit( + add_argument( + "check=False", + &call.arguments, + checker.indexer().comment_ranges(), + checker.locator().contents(), + ), + // If the function call contains `**kwargs`, mark the fix as unsafe. + if call + .arguments + .keywords + .iter() + .any(|keyword| keyword.arg.is_none()) + { + Applicability::Unsafe + } else { + Applicability::Safe + }, )); + checker.diagnostics.push(diagnostic); } } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/too_many_arguments.rs b/crates/ruff_linter/src/rules/pylint/rules/too_many_arguments.rs index 5ddd80ecbc37c..84e5740f6d987 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/too_many_arguments.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/too_many_arguments.rs @@ -1,8 +1,8 @@ -use ruff_python_ast::{Parameters, Stmt}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast as ast; use ruff_python_ast::identifier::Identifier; +use ruff_python_semantic::analyze::visibility; use crate::checkers::ast::Checker; @@ -58,12 +58,13 @@ impl Violation for TooManyArguments { } /// PLR0913 -pub(crate) fn too_many_arguments(checker: &mut Checker, parameters: &Parameters, stmt: &Stmt) { - let num_arguments = parameters +pub(crate) fn too_many_arguments(checker: &mut Checker, function_def: &ast::StmtFunctionDef) { + let num_arguments = function_def + .parameters .args .iter() - .chain(¶meters.kwonlyargs) - .chain(¶meters.posonlyargs) + .chain(&function_def.parameters.kwonlyargs) + .chain(&function_def.parameters.posonlyargs) .filter(|arg| { !checker .settings @@ -71,13 +72,22 @@ pub(crate) fn too_many_arguments(checker: &mut Checker, parameters: &Parameters, .is_match(&arg.parameter.name) }) .count(); + if num_arguments > checker.settings.pylint.max_args { + // Allow excessive arguments in `@override` or `@overload` methods, since they're required + // to adhere to the parent signature. + if visibility::is_override(&function_def.decorator_list, checker.semantic()) + || visibility::is_overload(&function_def.decorator_list, checker.semantic()) + { + return; + } + checker.diagnostics.push(Diagnostic::new( TooManyArguments { c_args: num_arguments, max_args: checker.settings.pylint.max_args, }, - stmt.identifier(), + function_def.identifier(), )); } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/too_many_positional.rs b/crates/ruff_linter/src/rules/pylint/rules/too_many_positional.rs new file mode 100644 index 0000000000000..bc424441c0b7d --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/too_many_positional.rs @@ -0,0 +1,90 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, identifier::Identifier}; +use ruff_python_semantic::analyze::visibility; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for function definitions that include too many positional arguments. +/// +/// By default, this rule allows up to five arguments, as configured by the +/// [`pylint.max-positional-args`] option. +/// +/// ## Why is this bad? +/// Functions with many arguments are harder to understand, maintain, and call. +/// This is especially true for functions with many positional arguments, as +/// providing arguments positionally is more error-prone and less clear to +/// readers than providing arguments by name. +/// +/// Consider refactoring functions with many arguments into smaller functions +/// with fewer arguments, using objects to group related arguments, or +/// migrating to keyword-only arguments. +/// +/// ## Example +/// ```python +/// def plot(x, y, z, color, mark, add_trendline): +/// ... +/// +/// +/// plot(1, 2, 3, "r", "*", True) +/// ``` +/// +/// Use instead: +/// ```python +/// def plot(x, y, z, *, color, mark, add_trendline): +/// ... +/// +/// +/// plot(1, 2, 3, color="r", mark="*", add_trendline=True) +/// ``` +/// +/// ## Options +/// - `pylint.max-positional-args` +#[violation] +pub struct TooManyPositional { + c_pos: usize, + max_pos: usize, +} + +impl Violation for TooManyPositional { + #[derive_message_formats] + fn message(&self) -> String { + let TooManyPositional { c_pos, max_pos } = self; + format!("Too many positional arguments: ({c_pos}/{max_pos})") + } +} + +/// PLR0917 +pub(crate) fn too_many_positional(checker: &mut Checker, function_def: &ast::StmtFunctionDef) { + let num_positional_args = function_def + .parameters + .args + .iter() + .chain(&function_def.parameters.posonlyargs) + .filter(|arg| { + !checker + .settings + .dummy_variable_rgx + .is_match(&arg.parameter.name) + }) + .count(); + + if num_positional_args > checker.settings.pylint.max_positional_args { + // Allow excessive arguments in `@override` or `@overload` methods, since they're required + // to adhere to the parent signature. + if visibility::is_override(&function_def.decorator_list, checker.semantic()) + || visibility::is_overload(&function_def.decorator_list, checker.semantic()) + { + return; + } + + checker.diagnostics.push(Diagnostic::new( + TooManyPositional { + c_pos: num_positional_args, + max_pos: checker.settings.pylint.max_positional_args, + }, + function_def.identifier(), + )); + } +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/unnecessary_dict_index_lookup.rs b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_dict_index_lookup.rs new file mode 100644 index 0000000000000..913279081fcc4 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_dict_index_lookup.rs @@ -0,0 +1,167 @@ +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::visitor::Visitor; +use ruff_python_ast::{self as ast, Expr, StmtFor}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; +use crate::rules::pylint::helpers::SequenceIndexVisitor; + +/// ## What it does +/// Checks for key-based dict accesses during `.items()` iterations. +/// +/// ## Why is this bad? +/// When iterating over a dict via `.items()`, the current value is already +/// available alongside its key. Using the key to look up the value is +/// unnecessary. +/// +/// ## Example +/// ```python +/// FRUITS = {"apple": 1, "orange": 10, "berry": 22} +/// +/// for fruit_name, fruit_count in FRUITS.items(): +/// print(FRUITS[fruit_name]) +/// ``` +/// +/// Use instead: +/// ```python +/// FRUITS = {"apple": 1, "orange": 10, "berry": 22} +/// +/// for fruit_name, fruit_count in FRUITS.items(): +/// print(fruit_count) +/// ``` +#[violation] +pub struct UnnecessaryDictIndexLookup; + +impl AlwaysFixableViolation for UnnecessaryDictIndexLookup { + #[derive_message_formats] + fn message(&self) -> String { + format!("Unnecessary lookup of dictionary value by key") + } + + fn fix_title(&self) -> String { + format!("Use existing variable") + } +} + +/// PLR1733 +pub(crate) fn unnecessary_dict_index_lookup(checker: &mut Checker, stmt_for: &StmtFor) { + let Some((dict_name, index_name, value_name)) = dict_items(&stmt_for.iter, &stmt_for.target) + else { + return; + }; + + let ranges = { + let mut visitor = SequenceIndexVisitor::new(&dict_name.id, &index_name.id, &value_name.id); + visitor.visit_body(&stmt_for.body); + visitor.visit_body(&stmt_for.orelse); + visitor.into_accesses() + }; + + for range in ranges { + let mut diagnostic = Diagnostic::new(UnnecessaryDictIndexLookup, range); + diagnostic.set_fix(Fix::safe_edits( + Edit::range_replacement(value_name.id.to_string(), range), + [noop(index_name), noop(value_name)], + )); + checker.diagnostics.push(diagnostic); + } +} + +/// PLR1733 +pub(crate) fn unnecessary_dict_index_lookup_comprehension(checker: &mut Checker, expr: &Expr) { + let (Expr::GeneratorExp(ast::ExprGeneratorExp { + elt, generators, .. + }) + | Expr::DictComp(ast::ExprDictComp { + value: elt, + generators, + .. + }) + | Expr::SetComp(ast::ExprSetComp { + elt, generators, .. + }) + | Expr::ListComp(ast::ExprListComp { + elt, generators, .. + })) = expr + else { + return; + }; + + for comp in generators { + let Some((dict_name, index_name, value_name)) = dict_items(&comp.iter, &comp.target) else { + continue; + }; + + let ranges = { + let mut visitor = + SequenceIndexVisitor::new(&dict_name.id, &index_name.id, &value_name.id); + visitor.visit_expr(elt.as_ref()); + for expr in &comp.ifs { + visitor.visit_expr(expr); + } + visitor.into_accesses() + }; + + for range in ranges { + let mut diagnostic = Diagnostic::new(UnnecessaryDictIndexLookup, range); + diagnostic.set_fix(Fix::safe_edits( + Edit::range_replacement(value_name.id.to_string(), range), + [noop(index_name), noop(value_name)], + )); + checker.diagnostics.push(diagnostic); + } + } +} + +fn dict_items<'a>( + call_expr: &'a Expr, + tuple_expr: &'a Expr, +) -> Option<(&'a ast::ExprName, &'a ast::ExprName, &'a ast::ExprName)> { + let ast::ExprCall { + func, arguments, .. + } = call_expr.as_call_expr()?; + + if !arguments.is_empty() { + return None; + } + let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() else { + return None; + }; + if attr != "items" { + return None; + } + + let Expr::Name(dict_name) = value.as_ref() else { + return None; + }; + + let Expr::Tuple(ast::ExprTuple { elts, .. }) = tuple_expr else { + return None; + }; + let [index, value] = elts.as_slice() else { + return None; + }; + + // Grab the variable names. + let Expr::Name(index_name) = index else { + return None; + }; + + let Expr::Name(value_name) = value else { + return None; + }; + + // If either of the variable names are intentionally ignored by naming them `_`, then don't + // emit. + if index_name.id == "_" || value_name.id == "_" { + return None; + } + + Some((dict_name, index_name, value_name)) +} + +/// Return a no-op edit for the given name. +fn noop(name: &ast::ExprName) -> Edit { + Edit::range_replacement(name.id.to_string(), name.range()) +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs new file mode 100644 index 0000000000000..461a8d56c94c6 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs @@ -0,0 +1,168 @@ +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::visitor::Visitor; +use ruff_python_ast::{self as ast, Expr, StmtFor}; +use ruff_python_semantic::SemanticModel; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; +use crate::rules::pylint::helpers::SequenceIndexVisitor; + +/// ## What it does +/// Checks for index-based list accesses during `enumerate` iterations. +/// +/// ## Why is this bad? +/// When iterating over a list with `enumerate`, the current item is already +/// available alongside its index. Using the index to look up the item is +/// unnecessary. +/// +/// ## Example +/// ```python +/// letters = ["a", "b", "c"] +/// +/// for index, letter in enumerate(letters): +/// print(letters[index]) +/// ``` +/// +/// Use instead: +/// ```python +/// letters = ["a", "b", "c"] +/// +/// for index, letter in enumerate(letters): +/// print(letter) +/// ``` +#[violation] +pub struct UnnecessaryListIndexLookup; + +impl AlwaysFixableViolation for UnnecessaryListIndexLookup { + #[derive_message_formats] + fn message(&self) -> String { + format!("Unnecessary lookup of list item by index") + } + + fn fix_title(&self) -> String { + format!("Use existing variable") + } +} + +/// PLR1736 +pub(crate) fn unnecessary_list_index_lookup(checker: &mut Checker, stmt_for: &StmtFor) { + let Some((sequence, index_name, value_name)) = + enumerate_items(&stmt_for.iter, &stmt_for.target, checker.semantic()) + else { + return; + }; + + let ranges = { + let mut visitor = SequenceIndexVisitor::new(&sequence.id, &index_name.id, &value_name.id); + visitor.visit_body(&stmt_for.body); + visitor.visit_body(&stmt_for.orelse); + visitor.into_accesses() + }; + + for range in ranges { + let mut diagnostic = Diagnostic::new(UnnecessaryListIndexLookup, range); + diagnostic.set_fix(Fix::safe_edits( + Edit::range_replacement(value_name.id.to_string(), range), + [noop(index_name), noop(value_name)], + )); + checker.diagnostics.push(diagnostic); + } +} + +/// PLR1736 +pub(crate) fn unnecessary_list_index_lookup_comprehension(checker: &mut Checker, expr: &Expr) { + let (Expr::GeneratorExp(ast::ExprGeneratorExp { + elt, generators, .. + }) + | Expr::DictComp(ast::ExprDictComp { + value: elt, + generators, + .. + }) + | Expr::SetComp(ast::ExprSetComp { + elt, generators, .. + }) + | Expr::ListComp(ast::ExprListComp { + elt, generators, .. + })) = expr + else { + return; + }; + + for comp in generators { + let Some((sequence, index_name, value_name)) = + enumerate_items(&comp.iter, &comp.target, checker.semantic()) + else { + return; + }; + + let ranges = { + let mut visitor = + SequenceIndexVisitor::new(&sequence.id, &index_name.id, &value_name.id); + visitor.visit_expr(elt.as_ref()); + visitor.into_accesses() + }; + + for range in ranges { + let mut diagnostic = Diagnostic::new(UnnecessaryListIndexLookup, range); + diagnostic.set_fix(Fix::safe_edits( + Edit::range_replacement(value_name.id.to_string(), range), + [noop(index_name), noop(value_name)], + )); + checker.diagnostics.push(diagnostic); + } + } +} + +fn enumerate_items<'a>( + call_expr: &'a Expr, + tuple_expr: &'a Expr, + semantic: &SemanticModel, +) -> Option<(&'a ast::ExprName, &'a ast::ExprName, &'a ast::ExprName)> { + let ast::ExprCall { + func, arguments, .. + } = call_expr.as_call_expr()?; + + // Check that the function is the `enumerate` builtin. + if !semantic + .resolve_call_path(func.as_ref()) + .is_some_and(|call_path| matches!(call_path.as_slice(), ["builtins" | "", "enumerate"])) + { + return None; + } + + let Expr::Tuple(ast::ExprTuple { elts, .. }) = tuple_expr else { + return None; + }; + let [index, value] = elts.as_slice() else { + return None; + }; + + // Grab the variable names. + let Expr::Name(index_name) = index else { + return None; + }; + + let Expr::Name(value_name) = value else { + return None; + }; + + // If either of the variable names are intentionally ignored by naming them `_`, then don't + // emit. + if index_name.id == "_" || value_name.id == "_" { + return None; + } + + // Get the first argument of the enumerate call. + let Some(Expr::Name(sequence)) = arguments.args.first() else { + return None; + }; + + Some((sequence, index_name, value_name)) +} + +/// Return a no-op edit for the given name. +fn noop(name: &ast::ExprName) -> Edit { + Edit::range_replacement(name.id.to_string(), name.range()) +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/unspecified_encoding.rs b/crates/ruff_linter/src/rules/pylint/rules/unspecified_encoding.rs index 49c5575199cf9..b6728df692415 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/unspecified_encoding.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/unspecified_encoding.rs @@ -1,10 +1,16 @@ -use ruff_diagnostics::{Diagnostic, Violation}; +use anyhow::Result; + +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast as ast; use ruff_python_ast::call_path::{format_call_path, CallPath}; -use ruff_text_size::Ranged; +use ruff_python_ast::Expr; +use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; +use crate::fix::edits::add_argument; +use crate::importer::ImportRequest; +use crate::settings::types::PythonVersion; /// ## What it does /// Checks for uses of `open` and related calls without an explicit `encoding` @@ -15,7 +21,9 @@ use crate::checkers::ast::Checker; /// non-portable code, with differing behavior across platforms. /// /// Instead, consider using the `encoding` parameter to enforce a specific -/// encoding. +/// encoding. [PEP 597] recommends using `locale.getpreferredencoding(False)` +/// as the default encoding on versions earlier than Python 3.10, and +/// `encoding="locale"` on Python 3.10 and later. /// /// ## Example /// ```python @@ -29,13 +37,15 @@ use crate::checkers::ast::Checker; /// /// ## References /// - [Python documentation: `open`](https://docs.python.org/3/library/functions.html#open) +/// +/// [PEP 597]: https://peps.python.org/pep-0597/ #[violation] pub struct UnspecifiedEncoding { function_name: String, mode: Mode, } -impl Violation for UnspecifiedEncoding { +impl AlwaysFixableViolation for UnspecifiedEncoding { #[derive_message_formats] fn message(&self) -> String { let UnspecifiedEncoding { @@ -52,6 +62,10 @@ impl Violation for UnspecifiedEncoding { } } } + + fn fix_title(&self) -> String { + format!("Add explicit `encoding` argument") + } } /// PLW1514 @@ -70,29 +84,75 @@ pub(crate) fn unspecified_encoding(checker: &mut Checker, call: &ast::ExprCall) return; }; - checker.diagnostics.push(Diagnostic::new( + let mut diagnostic = Diagnostic::new( UnspecifiedEncoding { function_name, mode, }, call.func.range(), - )); + ); + + if checker.settings.target_version >= PythonVersion::Py310 { + diagnostic.set_fix(generate_keyword_fix(checker, call)); + } else { + diagnostic.try_set_fix(|| generate_import_fix(checker, call)); + } + + checker.diagnostics.push(diagnostic); +} + +/// Generate an [`Edit`] for Python 3.10 and later. +fn generate_keyword_fix(checker: &Checker, call: &ast::ExprCall) -> Fix { + Fix::unsafe_edit(add_argument( + &format!( + "encoding={}", + checker + .generator() + .expr(&Expr::StringLiteral(ast::ExprStringLiteral { + value: ast::StringLiteralValue::single(ast::StringLiteral { + value: "locale".to_string(), + unicode: false, + range: TextRange::default(), + }), + range: TextRange::default(), + })) + ), + &call.arguments, + checker.indexer().comment_ranges(), + checker.locator().contents(), + )) +} + +/// Generate an [`Edit`] for Python 3.9 and earlier. +fn generate_import_fix(checker: &Checker, call: &ast::ExprCall) -> Result { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import("locale", "getpreferredencoding"), + call.start(), + checker.semantic(), + )?; + let argument_edit = add_argument( + &format!("encoding={binding}(False)"), + &call.arguments, + checker.indexer().comment_ranges(), + checker.locator().contents(), + ); + Ok(Fix::unsafe_edits(import_edit, [argument_edit])) } /// Returns `true` if the given expression is a string literal containing a `b` character. -fn is_binary_mode(expr: &ast::Expr) -> Option { - Some(expr.as_string_literal_expr()?.value.contains('b')) +fn is_binary_mode(expr: &Expr) -> Option { + Some( + expr.as_string_literal_expr()? + .value + .chars() + .any(|c| c == 'b'), + ) } /// Returns `true` if the given call lacks an explicit `encoding`. fn is_violation(call: &ast::ExprCall, call_path: &CallPath) -> bool { // If we have something like `*args`, which might contain the encoding argument, abort. - if call - .arguments - .args - .iter() - .any(ruff_python_ast::Expr::is_starred_expr) - { + if call.arguments.args.iter().any(Expr::is_starred_expr) { return false; } // If we have something like `**kwargs`, which might contain the encoding argument, abort. diff --git a/crates/ruff_linter/src/rules/pylint/settings.rs b/crates/ruff_linter/src/rules/pylint/settings.rs index 4925211952ebb..020390704c7f8 100644 --- a/crates/ruff_linter/src/rules/pylint/settings.rs +++ b/crates/ruff_linter/src/rules/pylint/settings.rs @@ -1,5 +1,6 @@ //! Settings for the `pylint` plugin. +use rustc_hash::FxHashSet; use serde::{Deserialize, Serialize}; use ruff_macros::CacheKey; @@ -36,7 +37,9 @@ impl ConstantType { #[derive(Debug, CacheKey)] pub struct Settings { pub allow_magic_value_types: Vec, + pub allow_dunder_method_names: FxHashSet, pub max_args: usize, + pub max_positional_args: usize, pub max_returns: usize, pub max_bool_expr: usize, pub max_branches: usize, @@ -48,7 +51,9 @@ impl Default for Settings { fn default() -> Self { Self { allow_magic_value_types: vec![ConstantType::Str, ConstantType::Bytes], + allow_dunder_method_names: FxHashSet::default(), max_args: 5, + max_positional_args: 5, max_returns: 6, max_bool_expr: 5, max_branches: 12, diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0202_no_method_decorator.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0202_no_method_decorator.py.snap new file mode 100644 index 0000000000000..d6fb47065915b --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0202_no_method_decorator.py.snap @@ -0,0 +1,31 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +no_method_decorator.py:9:5: PLR0202 [*] Class method defined without decorator + | + 7 | self.color = color + 8 | + 9 | def pick_colors(cls, *args): # [no-classmethod-decorator] + | PLR0202 +10 | """classmethod to pick fruit colors""" +11 | cls.COLORS = args + | + = help: Add @classmethod decorator + +ℹ Safe fix +6 6 | def __init__(self, color): +7 7 | self.color = color +8 8 | + 9 |+ @classmethod +9 10 | def pick_colors(cls, *args): # [no-classmethod-decorator] +10 11 | """classmethod to pick fruit colors""" +11 12 | cls.COLORS = args +12 13 | +13 |- pick_colors = classmethod(pick_colors) +14 14 | + 15 |+ +15 16 | def pick_one_color(): # [no-staticmethod-decorator] +16 17 | """staticmethod to pick one fruit color""" +17 18 | return choice(Fruit.COLORS) + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0203_no_method_decorator.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0203_no_method_decorator.py.snap new file mode 100644 index 0000000000000..a1fe06afafc1a --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0203_no_method_decorator.py.snap @@ -0,0 +1,27 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +no_method_decorator.py:15:5: PLR0203 [*] Static method defined without decorator + | +13 | pick_colors = classmethod(pick_colors) +14 | +15 | def pick_one_color(): # [no-staticmethod-decorator] + | PLR0203 +16 | """staticmethod to pick one fruit color""" +17 | return choice(Fruit.COLORS) + | + = help: Add @staticmethod decorator + +ℹ Safe fix +12 12 | +13 13 | pick_colors = classmethod(pick_colors) +14 14 | + 15 |+ @staticmethod +15 16 | def pick_one_color(): # [no-staticmethod-decorator] +16 17 | """staticmethod to pick one fruit color""" +17 18 | return choice(Fruit.COLORS) +18 19 | +19 |- pick_one_color = staticmethod(pick_one_color) + 20 |+ + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0917_too_many_positional.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0917_too_many_positional.py.snap new file mode 100644 index 0000000000000..4578419f43545 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0917_too_many_positional.py.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +too_many_positional.py:1:5: PLR0917 Too many positional arguments: (8/5) + | +1 | def f(x, y, z, t, u, v, w, r): # Too many positional arguments (8/3) + | ^ PLR0917 +2 | pass + | + +too_many_positional.py:21:5: PLR0917 Too many positional arguments: (6/5) + | +21 | def f(x, y, z, /, u, v, w): # Too many positional arguments (6/3) + | ^ PLR0917 +22 | pass + | + +too_many_positional.py:29:5: PLR0917 Too many positional arguments: (6/5) + | +29 | def f(x, y, z, a, b, c, *, u, v, w): # Too many positional arguments (6/3) + | ^ PLR0917 +30 | pass + | + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1733_unnecessary_dict_index_lookup.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1733_unnecessary_dict_index_lookup.py.snap new file mode 100644 index 0000000000000..1f52c2ffe1329 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1733_unnecessary_dict_index_lookup.py.snap @@ -0,0 +1,124 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +unnecessary_dict_index_lookup.py:4:6: PLR1733 [*] Unnecessary lookup of dictionary value by key + | +3 | def fix_these(): +4 | [FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()] # PLR1733 + | ^^^^^^^^^^^^^^^^^^ PLR1733 +5 | {FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +6 | {fruit_name: FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 + | + = help: Use existing variable + +ℹ Safe fix +1 1 | FRUITS = {"apple": 1, "orange": 10, "berry": 22} +2 2 | +3 3 | def fix_these(): +4 |- [FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()] # PLR1733 + 4 |+ [fruit_count for fruit_name, fruit_count in FRUITS.items()] # PLR1733 +5 5 | {FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +6 6 | {fruit_name: FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +7 7 | + +unnecessary_dict_index_lookup.py:5:6: PLR1733 [*] Unnecessary lookup of dictionary value by key + | +3 | def fix_these(): +4 | [FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()] # PLR1733 +5 | {FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 + | ^^^^^^^^^^^^^^^^^^ PLR1733 +6 | {fruit_name: FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 + | + = help: Use existing variable + +ℹ Safe fix +2 2 | +3 3 | def fix_these(): +4 4 | [FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()] # PLR1733 +5 |- {FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 + 5 |+ {fruit_count for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +6 6 | {fruit_name: FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +7 7 | +8 8 | for fruit_name, fruit_count in FRUITS.items(): + +unnecessary_dict_index_lookup.py:6:18: PLR1733 [*] Unnecessary lookup of dictionary value by key + | +4 | [FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()] # PLR1733 +5 | {FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +6 | {fruit_name: FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 + | ^^^^^^^^^^^^^^^^^^ PLR1733 +7 | +8 | for fruit_name, fruit_count in FRUITS.items(): + | + = help: Use existing variable + +ℹ Safe fix +3 3 | def fix_these(): +4 4 | [FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()] # PLR1733 +5 5 | {FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +6 |- {fruit_name: FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 + 6 |+ {fruit_name: fruit_count for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +7 7 | +8 8 | for fruit_name, fruit_count in FRUITS.items(): +9 9 | print(FRUITS[fruit_name]) # PLR1733 + +unnecessary_dict_index_lookup.py:9:15: PLR1733 [*] Unnecessary lookup of dictionary value by key + | + 8 | for fruit_name, fruit_count in FRUITS.items(): + 9 | print(FRUITS[fruit_name]) # PLR1733 + | ^^^^^^^^^^^^^^^^^^ PLR1733 +10 | blah = FRUITS[fruit_name] # PLR1733 +11 | assert FRUITS[fruit_name] == "pear" # PLR1733 + | + = help: Use existing variable + +ℹ Safe fix +6 6 | {fruit_name: FRUITS[fruit_name] for fruit_name, fruit_count in FRUITS.items()} # PLR1733 +7 7 | +8 8 | for fruit_name, fruit_count in FRUITS.items(): +9 |- print(FRUITS[fruit_name]) # PLR1733 + 9 |+ print(fruit_count) # PLR1733 +10 10 | blah = FRUITS[fruit_name] # PLR1733 +11 11 | assert FRUITS[fruit_name] == "pear" # PLR1733 +12 12 | + +unnecessary_dict_index_lookup.py:10:16: PLR1733 [*] Unnecessary lookup of dictionary value by key + | + 8 | for fruit_name, fruit_count in FRUITS.items(): + 9 | print(FRUITS[fruit_name]) # PLR1733 +10 | blah = FRUITS[fruit_name] # PLR1733 + | ^^^^^^^^^^^^^^^^^^ PLR1733 +11 | assert FRUITS[fruit_name] == "pear" # PLR1733 + | + = help: Use existing variable + +ℹ Safe fix +7 7 | +8 8 | for fruit_name, fruit_count in FRUITS.items(): +9 9 | print(FRUITS[fruit_name]) # PLR1733 +10 |- blah = FRUITS[fruit_name] # PLR1733 + 10 |+ blah = fruit_count # PLR1733 +11 11 | assert FRUITS[fruit_name] == "pear" # PLR1733 +12 12 | +13 13 | + +unnecessary_dict_index_lookup.py:11:16: PLR1733 [*] Unnecessary lookup of dictionary value by key + | + 9 | print(FRUITS[fruit_name]) # PLR1733 +10 | blah = FRUITS[fruit_name] # PLR1733 +11 | assert FRUITS[fruit_name] == "pear" # PLR1733 + | ^^^^^^^^^^^^^^^^^^ PLR1733 + | + = help: Use existing variable + +ℹ Safe fix +8 8 | for fruit_name, fruit_count in FRUITS.items(): +9 9 | print(FRUITS[fruit_name]) # PLR1733 +10 10 | blah = FRUITS[fruit_name] # PLR1733 +11 |- assert FRUITS[fruit_name] == "pear" # PLR1733 + 11 |+ assert fruit_count == "pear" # PLR1733 +12 12 | +13 13 | +14 14 | def dont_fix_these(): + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1736_unnecessary_list_index_lookup.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1736_unnecessary_list_index_lookup.py.snap new file mode 100644 index 0000000000000..880422eab6674 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1736_unnecessary_list_index_lookup.py.snap @@ -0,0 +1,185 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +unnecessary_list_index_lookup.py:7:6: PLR1736 [*] Unnecessary lookup of list item by index + | +6 | def fix_these(): +7 | [letters[index] for index, letter in enumerate(letters)] # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 +8 | {letters[index] for index, letter in enumerate(letters)} # PLR1736 +9 | {letter: letters[index] for index, letter in enumerate(letters)} # PLR1736 + | + = help: Use existing variable + +ℹ Safe fix +4 4 | +5 5 | +6 6 | def fix_these(): +7 |- [letters[index] for index, letter in enumerate(letters)] # PLR1736 + 7 |+ [letter for index, letter in enumerate(letters)] # PLR1736 +8 8 | {letters[index] for index, letter in enumerate(letters)} # PLR1736 +9 9 | {letter: letters[index] for index, letter in enumerate(letters)} # PLR1736 +10 10 | + +unnecessary_list_index_lookup.py:8:6: PLR1736 [*] Unnecessary lookup of list item by index + | +6 | def fix_these(): +7 | [letters[index] for index, letter in enumerate(letters)] # PLR1736 +8 | {letters[index] for index, letter in enumerate(letters)} # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 +9 | {letter: letters[index] for index, letter in enumerate(letters)} # PLR1736 + | + = help: Use existing variable + +ℹ Safe fix +5 5 | +6 6 | def fix_these(): +7 7 | [letters[index] for index, letter in enumerate(letters)] # PLR1736 +8 |- {letters[index] for index, letter in enumerate(letters)} # PLR1736 + 8 |+ {letter for index, letter in enumerate(letters)} # PLR1736 +9 9 | {letter: letters[index] for index, letter in enumerate(letters)} # PLR1736 +10 10 | +11 11 | for index, letter in enumerate(letters): + +unnecessary_list_index_lookup.py:9:14: PLR1736 [*] Unnecessary lookup of list item by index + | + 7 | [letters[index] for index, letter in enumerate(letters)] # PLR1736 + 8 | {letters[index] for index, letter in enumerate(letters)} # PLR1736 + 9 | {letter: letters[index] for index, letter in enumerate(letters)} # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 +10 | +11 | for index, letter in enumerate(letters): + | + = help: Use existing variable + +ℹ Safe fix +6 6 | def fix_these(): +7 7 | [letters[index] for index, letter in enumerate(letters)] # PLR1736 +8 8 | {letters[index] for index, letter in enumerate(letters)} # PLR1736 +9 |- {letter: letters[index] for index, letter in enumerate(letters)} # PLR1736 + 9 |+ {letter: letter for index, letter in enumerate(letters)} # PLR1736 +10 10 | +11 11 | for index, letter in enumerate(letters): +12 12 | print(letters[index]) # PLR1736 + +unnecessary_list_index_lookup.py:12:15: PLR1736 [*] Unnecessary lookup of list item by index + | +11 | for index, letter in enumerate(letters): +12 | print(letters[index]) # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 +13 | blah = letters[index] # PLR1736 +14 | assert letters[index] == "d" # PLR1736 + | + = help: Use existing variable + +ℹ Safe fix +9 9 | {letter: letters[index] for index, letter in enumerate(letters)} # PLR1736 +10 10 | +11 11 | for index, letter in enumerate(letters): +12 |- print(letters[index]) # PLR1736 + 12 |+ print(letter) # PLR1736 +13 13 | blah = letters[index] # PLR1736 +14 14 | assert letters[index] == "d" # PLR1736 +15 15 | + +unnecessary_list_index_lookup.py:13:16: PLR1736 [*] Unnecessary lookup of list item by index + | +11 | for index, letter in enumerate(letters): +12 | print(letters[index]) # PLR1736 +13 | blah = letters[index] # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 +14 | assert letters[index] == "d" # PLR1736 + | + = help: Use existing variable + +ℹ Safe fix +10 10 | +11 11 | for index, letter in enumerate(letters): +12 12 | print(letters[index]) # PLR1736 +13 |- blah = letters[index] # PLR1736 + 13 |+ blah = letter # PLR1736 +14 14 | assert letters[index] == "d" # PLR1736 +15 15 | +16 16 | for index, letter in builtins.enumerate(letters): + +unnecessary_list_index_lookup.py:14:16: PLR1736 [*] Unnecessary lookup of list item by index + | +12 | print(letters[index]) # PLR1736 +13 | blah = letters[index] # PLR1736 +14 | assert letters[index] == "d" # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 +15 | +16 | for index, letter in builtins.enumerate(letters): + | + = help: Use existing variable + +ℹ Safe fix +11 11 | for index, letter in enumerate(letters): +12 12 | print(letters[index]) # PLR1736 +13 13 | blah = letters[index] # PLR1736 +14 |- assert letters[index] == "d" # PLR1736 + 14 |+ assert letter == "d" # PLR1736 +15 15 | +16 16 | for index, letter in builtins.enumerate(letters): +17 17 | print(letters[index]) # PLR1736 + +unnecessary_list_index_lookup.py:17:15: PLR1736 [*] Unnecessary lookup of list item by index + | +16 | for index, letter in builtins.enumerate(letters): +17 | print(letters[index]) # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 +18 | blah = letters[index] # PLR1736 +19 | assert letters[index] == "d" # PLR1736 + | + = help: Use existing variable + +ℹ Safe fix +14 14 | assert letters[index] == "d" # PLR1736 +15 15 | +16 16 | for index, letter in builtins.enumerate(letters): +17 |- print(letters[index]) # PLR1736 + 17 |+ print(letter) # PLR1736 +18 18 | blah = letters[index] # PLR1736 +19 19 | assert letters[index] == "d" # PLR1736 +20 20 | + +unnecessary_list_index_lookup.py:18:16: PLR1736 [*] Unnecessary lookup of list item by index + | +16 | for index, letter in builtins.enumerate(letters): +17 | print(letters[index]) # PLR1736 +18 | blah = letters[index] # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 +19 | assert letters[index] == "d" # PLR1736 + | + = help: Use existing variable + +ℹ Safe fix +15 15 | +16 16 | for index, letter in builtins.enumerate(letters): +17 17 | print(letters[index]) # PLR1736 +18 |- blah = letters[index] # PLR1736 + 18 |+ blah = letter # PLR1736 +19 19 | assert letters[index] == "d" # PLR1736 +20 20 | +21 21 | + +unnecessary_list_index_lookup.py:19:16: PLR1736 [*] Unnecessary lookup of list item by index + | +17 | print(letters[index]) # PLR1736 +18 | blah = letters[index] # PLR1736 +19 | assert letters[index] == "d" # PLR1736 + | ^^^^^^^^^^^^^^ PLR1736 + | + = help: Use existing variable + +ℹ Safe fix +16 16 | for index, letter in builtins.enumerate(letters): +17 17 | print(letters[index]) # PLR1736 +18 18 | blah = letters[index] # PLR1736 +19 |- assert letters[index] == "d" # PLR1736 + 19 |+ assert letter == "d" # PLR1736 +20 20 | +21 21 | +22 22 | def dont_fix_these(): + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0127_self_assigning_variable.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0127_self_assigning_variable.py.snap index 80ecb80e58fdd..882bd21a0a030 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0127_self_assigning_variable.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0127_self_assigning_variable.py.snap @@ -347,6 +347,7 @@ self_assigning_variable.py:24:1: PLW0127 Self-assignment of variable `foo` 24 | foo: int = foo | ^^^ PLW0127 25 | bar: int = bar +26 | foo = foo = bar | self_assigning_variable.py:25:1: PLW0127 Self-assignment of variable `bar` @@ -355,8 +356,56 @@ self_assigning_variable.py:25:1: PLW0127 Self-assignment of variable `bar` 24 | foo: int = foo 25 | bar: int = bar | ^^^ PLW0127 -26 | -27 | # Non-errors. +26 | foo = foo = bar +27 | (foo, bar) = (foo, bar) = baz + | + +self_assigning_variable.py:26:1: PLW0127 Self-assignment of variable `foo` + | +24 | foo: int = foo +25 | bar: int = bar +26 | foo = foo = bar + | ^^^ PLW0127 +27 | (foo, bar) = (foo, bar) = baz +28 | (foo, bar) = baz = (foo, bar) = 1 + | + +self_assigning_variable.py:27:2: PLW0127 Self-assignment of variable `foo` + | +25 | bar: int = bar +26 | foo = foo = bar +27 | (foo, bar) = (foo, bar) = baz + | ^^^ PLW0127 +28 | (foo, bar) = baz = (foo, bar) = 1 + | + +self_assigning_variable.py:27:7: PLW0127 Self-assignment of variable `bar` + | +25 | bar: int = bar +26 | foo = foo = bar +27 | (foo, bar) = (foo, bar) = baz + | ^^^ PLW0127 +28 | (foo, bar) = baz = (foo, bar) = 1 + | + +self_assigning_variable.py:28:2: PLW0127 Self-assignment of variable `foo` + | +26 | foo = foo = bar +27 | (foo, bar) = (foo, bar) = baz +28 | (foo, bar) = baz = (foo, bar) = 1 + | ^^^ PLW0127 +29 | +30 | # Non-errors. + | + +self_assigning_variable.py:28:7: PLW0127 Self-assignment of variable `bar` + | +26 | foo = foo = bar +27 | (foo, bar) = (foo, bar) = baz +28 | (foo, bar) = baz = (foo, bar) = 1 + | ^^^ PLW0127 +29 | +30 | # Non-errors. | diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1510_subprocess_run_without_check.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1510_subprocess_run_without_check.py.snap index b0306f17a2d42..7419c16569584 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1510_subprocess_run_without_check.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1510_subprocess_run_without_check.py.snap @@ -1,22 +1,87 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -subprocess_run_without_check.py:4:1: PLW1510 `subprocess.run` without explicit `check` argument +subprocess_run_without_check.py:4:1: PLW1510 [*] `subprocess.run` without explicit `check` argument | 3 | # Errors. 4 | subprocess.run("ls") | ^^^^^^^^^^^^^^ PLW1510 5 | subprocess.run("ls", shell=True) +6 | subprocess.run( | + = help: Add explicit `check=False` -subprocess_run_without_check.py:5:1: PLW1510 `subprocess.run` without explicit `check` argument +ℹ Safe fix +1 1 | import subprocess +2 2 | +3 3 | # Errors. +4 |-subprocess.run("ls") + 4 |+subprocess.run("ls", check=False) +5 5 | subprocess.run("ls", shell=True) +6 6 | subprocess.run( +7 7 | ["ls"], + +subprocess_run_without_check.py:5:1: PLW1510 [*] `subprocess.run` without explicit `check` argument | 3 | # Errors. 4 | subprocess.run("ls") 5 | subprocess.run("ls", shell=True) | ^^^^^^^^^^^^^^ PLW1510 -6 | -7 | # Non-errors. +6 | subprocess.run( +7 | ["ls"], + | + = help: Add explicit `check=False` + +ℹ Safe fix +2 2 | +3 3 | # Errors. +4 4 | subprocess.run("ls") +5 |-subprocess.run("ls", shell=True) + 5 |+subprocess.run("ls", shell=True, check=False) +6 6 | subprocess.run( +7 7 | ["ls"], +8 8 | shell=False, + +subprocess_run_without_check.py:6:1: PLW1510 [*] `subprocess.run` without explicit `check` argument | +4 | subprocess.run("ls") +5 | subprocess.run("ls", shell=True) +6 | subprocess.run( + | ^^^^^^^^^^^^^^ PLW1510 +7 | ["ls"], +8 | shell=False, + | + = help: Add explicit `check=False` + +ℹ Safe fix +5 5 | subprocess.run("ls", shell=True) +6 6 | subprocess.run( +7 7 | ["ls"], +8 |- shell=False, + 8 |+ shell=False, check=False, +9 9 | ) +10 10 | subprocess.run(["ls"], **kwargs) +11 11 | + +subprocess_run_without_check.py:10:1: PLW1510 [*] `subprocess.run` without explicit `check` argument + | + 8 | shell=False, + 9 | ) +10 | subprocess.run(["ls"], **kwargs) + | ^^^^^^^^^^^^^^ PLW1510 +11 | +12 | # Non-errors. + | + = help: Add explicit `check=False` + +ℹ Unsafe fix +7 7 | ["ls"], +8 8 | shell=False, +9 9 | ) +10 |-subprocess.run(["ls"], **kwargs) + 10 |+subprocess.run(["ls"], **kwargs, check=False) +11 11 | +12 12 | # Non-errors. +13 13 | subprocess.run("ls", check=True) diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1514_unspecified_encoding.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1514_unspecified_encoding.py.snap index d10f3d3b633fd..9ceaf09daf820 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1514_unspecified_encoding.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1514_unspecified_encoding.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -unspecified_encoding.py:8:1: PLW1514 `open` in text mode without explicit `encoding` argument +unspecified_encoding.py:8:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument | 7 | # Errors. 8 | open("test.txt") @@ -9,8 +9,19 @@ unspecified_encoding.py:8:1: PLW1514 `open` in text mode without explicit `encod 9 | io.TextIOWrapper(io.FileIO("test.txt")) 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) | + = help: Add explicit `encoding` argument -unspecified_encoding.py:9:1: PLW1514 `io.TextIOWrapper` without explicit `encoding` argument +ℹ Unsafe fix +5 5 | import codecs +6 6 | +7 7 | # Errors. +8 |-open("test.txt") + 8 |+open("test.txt", encoding="locale") +9 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 11 | tempfile.NamedTemporaryFile("w") + +unspecified_encoding.py:9:1: PLW1514 [*] `io.TextIOWrapper` without explicit `encoding` argument | 7 | # Errors. 8 | open("test.txt") @@ -19,8 +30,19 @@ unspecified_encoding.py:9:1: PLW1514 `io.TextIOWrapper` without explicit `encodi 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) 11 | tempfile.NamedTemporaryFile("w") | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +6 6 | +7 7 | # Errors. +8 8 | open("test.txt") +9 |-io.TextIOWrapper(io.FileIO("test.txt")) + 9 |+io.TextIOWrapper(io.FileIO("test.txt"), encoding="locale") +10 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 11 | tempfile.NamedTemporaryFile("w") +12 12 | tempfile.TemporaryFile("w") -unspecified_encoding.py:10:1: PLW1514 `io.TextIOWrapper` without explicit `encoding` argument +unspecified_encoding.py:10:1: PLW1514 [*] `io.TextIOWrapper` without explicit `encoding` argument | 8 | open("test.txt") 9 | io.TextIOWrapper(io.FileIO("test.txt")) @@ -29,8 +51,19 @@ unspecified_encoding.py:10:1: PLW1514 `io.TextIOWrapper` without explicit `encod 11 | tempfile.NamedTemporaryFile("w") 12 | tempfile.TemporaryFile("w") | + = help: Add explicit `encoding` argument -unspecified_encoding.py:11:1: PLW1514 `tempfile.NamedTemporaryFile` in text mode without explicit `encoding` argument +ℹ Unsafe fix +7 7 | # Errors. +8 8 | open("test.txt") +9 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 |-hugo.TextIOWrapper(hugo.FileIO("test.txt")) + 10 |+hugo.TextIOWrapper(hugo.FileIO("test.txt"), encoding="locale") +11 11 | tempfile.NamedTemporaryFile("w") +12 12 | tempfile.TemporaryFile("w") +13 13 | codecs.open("test.txt") + +unspecified_encoding.py:11:1: PLW1514 [*] `tempfile.NamedTemporaryFile` in text mode without explicit `encoding` argument | 9 | io.TextIOWrapper(io.FileIO("test.txt")) 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) @@ -39,8 +72,19 @@ unspecified_encoding.py:11:1: PLW1514 `tempfile.NamedTemporaryFile` in text mode 12 | tempfile.TemporaryFile("w") 13 | codecs.open("test.txt") | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +8 8 | open("test.txt") +9 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 |-tempfile.NamedTemporaryFile("w") + 11 |+tempfile.NamedTemporaryFile("w", encoding="locale") +12 12 | tempfile.TemporaryFile("w") +13 13 | codecs.open("test.txt") +14 14 | tempfile.SpooledTemporaryFile(0, "w") -unspecified_encoding.py:12:1: PLW1514 `tempfile.TemporaryFile` in text mode without explicit `encoding` argument +unspecified_encoding.py:12:1: PLW1514 [*] `tempfile.TemporaryFile` in text mode without explicit `encoding` argument | 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) 11 | tempfile.NamedTemporaryFile("w") @@ -49,8 +93,19 @@ unspecified_encoding.py:12:1: PLW1514 `tempfile.TemporaryFile` in text mode with 13 | codecs.open("test.txt") 14 | tempfile.SpooledTemporaryFile(0, "w") | + = help: Add explicit `encoding` argument -unspecified_encoding.py:13:1: PLW1514 `codecs.open` in text mode without explicit `encoding` argument +ℹ Unsafe fix +9 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 11 | tempfile.NamedTemporaryFile("w") +12 |-tempfile.TemporaryFile("w") + 12 |+tempfile.TemporaryFile("w", encoding="locale") +13 13 | codecs.open("test.txt") +14 14 | tempfile.SpooledTemporaryFile(0, "w") +15 15 | + +unspecified_encoding.py:13:1: PLW1514 [*] `codecs.open` in text mode without explicit `encoding` argument | 11 | tempfile.NamedTemporaryFile("w") 12 | tempfile.TemporaryFile("w") @@ -58,8 +113,19 @@ unspecified_encoding.py:13:1: PLW1514 `codecs.open` in text mode without explici | ^^^^^^^^^^^ PLW1514 14 | tempfile.SpooledTemporaryFile(0, "w") | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +10 10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 11 | tempfile.NamedTemporaryFile("w") +12 12 | tempfile.TemporaryFile("w") +13 |-codecs.open("test.txt") + 13 |+codecs.open("test.txt", encoding="locale") +14 14 | tempfile.SpooledTemporaryFile(0, "w") +15 15 | +16 16 | # Non-errors. -unspecified_encoding.py:14:1: PLW1514 `tempfile.SpooledTemporaryFile` in text mode without explicit `encoding` argument +unspecified_encoding.py:14:1: PLW1514 [*] `tempfile.SpooledTemporaryFile` in text mode without explicit `encoding` argument | 12 | tempfile.TemporaryFile("w") 13 | codecs.open("test.txt") @@ -68,5 +134,223 @@ unspecified_encoding.py:14:1: PLW1514 `tempfile.SpooledTemporaryFile` in text mo 15 | 16 | # Non-errors. | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +11 11 | tempfile.NamedTemporaryFile("w") +12 12 | tempfile.TemporaryFile("w") +13 13 | codecs.open("test.txt") +14 |-tempfile.SpooledTemporaryFile(0, "w") + 14 |+tempfile.SpooledTemporaryFile(0, "w", encoding="locale") +15 15 | +16 16 | # Non-errors. +17 17 | open("test.txt", encoding="utf-8") + +unspecified_encoding.py:46:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +44 | tempfile.SpooledTemporaryFile(0, ) +45 | +46 | open("test.txt",) + | ^^^^ PLW1514 +47 | open() +48 | open( + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +43 43 | tempfile.SpooledTemporaryFile(0, "wb") +44 44 | tempfile.SpooledTemporaryFile(0, ) +45 45 | +46 |-open("test.txt",) + 46 |+open("test.txt", encoding="locale",) +47 47 | open() +48 48 | open( +49 49 | "test.txt", # comment + +unspecified_encoding.py:47:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +46 | open("test.txt",) +47 | open() + | ^^^^ PLW1514 +48 | open( +49 | "test.txt", # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +44 44 | tempfile.SpooledTemporaryFile(0, ) +45 45 | +46 46 | open("test.txt",) +47 |-open() + 47 |+open(encoding="locale") +48 48 | open( +49 49 | "test.txt", # comment +50 50 | ) + +unspecified_encoding.py:48:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +46 | open("test.txt",) +47 | open() +48 | open( + | ^^^^ PLW1514 +49 | "test.txt", # comment +50 | ) + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +46 46 | open("test.txt",) +47 47 | open() +48 48 | open( +49 |- "test.txt", # comment + 49 |+ "test.txt", encoding="locale", # comment +50 50 | ) +51 51 | open( +52 52 | "test.txt", + +unspecified_encoding.py:51:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +49 | "test.txt", # comment +50 | ) +51 | open( + | ^^^^ PLW1514 +52 | "test.txt", +53 | # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +49 49 | "test.txt", # comment +50 50 | ) +51 51 | open( +52 |- "test.txt", + 52 |+ "test.txt", encoding="locale", +53 53 | # comment +54 54 | ) +55 55 | open(("test.txt"),) + +unspecified_encoding.py:55:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +53 | # comment +54 | ) +55 | open(("test.txt"),) + | ^^^^ PLW1514 +56 | open( +57 | ("test.txt"), # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +52 52 | "test.txt", +53 53 | # comment +54 54 | ) +55 |-open(("test.txt"),) + 55 |+open(("test.txt"), encoding="locale",) +56 56 | open( +57 57 | ("test.txt"), # comment +58 58 | ) + +unspecified_encoding.py:56:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +54 | ) +55 | open(("test.txt"),) +56 | open( + | ^^^^ PLW1514 +57 | ("test.txt"), # comment +58 | ) + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +54 54 | ) +55 55 | open(("test.txt"),) +56 56 | open( +57 |- ("test.txt"), # comment + 57 |+ ("test.txt"), encoding="locale", # comment +58 58 | ) +59 59 | open( +60 60 | ("test.txt"), + +unspecified_encoding.py:59:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +57 | ("test.txt"), # comment +58 | ) +59 | open( + | ^^^^ PLW1514 +60 | ("test.txt"), +61 | # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +57 57 | ("test.txt"), # comment +58 58 | ) +59 59 | open( +60 |- ("test.txt"), + 60 |+ ("test.txt"), encoding="locale", +61 61 | # comment +62 62 | ) +63 63 | + +unspecified_encoding.py:64:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +62 | ) +63 | +64 | open((("test.txt")),) + | ^^^^ PLW1514 +65 | open( +66 | (("test.txt")), # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +61 61 | # comment +62 62 | ) +63 63 | +64 |-open((("test.txt")),) + 64 |+open((("test.txt")), encoding="locale",) +65 65 | open( +66 66 | (("test.txt")), # comment +67 67 | ) + +unspecified_encoding.py:65:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +64 | open((("test.txt")),) +65 | open( + | ^^^^ PLW1514 +66 | (("test.txt")), # comment +67 | ) + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +63 63 | +64 64 | open((("test.txt")),) +65 65 | open( +66 |- (("test.txt")), # comment + 66 |+ (("test.txt")), encoding="locale", # comment +67 67 | ) +68 68 | open( +69 69 | (("test.txt")), + +unspecified_encoding.py:68:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +66 | (("test.txt")), # comment +67 | ) +68 | open( + | ^^^^ PLW1514 +69 | (("test.txt")), +70 | # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +66 66 | (("test.txt")), # comment +67 67 | ) +68 68 | open( +69 |- (("test.txt")), + 69 |+ (("test.txt")), encoding="locale", +70 70 | # comment +71 71 | ) diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_positional_args.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_positional_args.snap new file mode 100644 index 0000000000000..98c964820770c --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_positional_args.snap @@ -0,0 +1,22 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +too_many_positional_params.py:3:5: PLR0917 Too many positional arguments: (7/4) + | +1 | # Too many positional arguments (7/4) for max_positional=4 +2 | # OK for dummy_variable_rgx ~ "skip_.*" +3 | def f(w, x, y, z, skip_t, skip_u, skip_v): + | ^ PLR0917 +4 | pass + | + +too_many_positional_params.py:9:5: PLR0917 Too many positional arguments: (7/4) + | + 7 | # Too many positional arguments (7/4) for max_args=4 + 8 | # Too many positional arguments (7/3) for dummy_variable_rgx ~ "skip_.*" + 9 | def f(w, x, y, z, t, u, v): + | ^ PLR0917 +10 | pass + | + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__unspecified_encoding_python39_or_lower.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__unspecified_encoding_python39_or_lower.snap new file mode 100644 index 0000000000000..1390eeede0cf3 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__unspecified_encoding_python39_or_lower.snap @@ -0,0 +1,477 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +unspecified_encoding.py:8:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | + 7 | # Errors. + 8 | open("test.txt") + | ^^^^ PLW1514 + 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 |-open("test.txt") + 9 |+open("test.txt", encoding=locale.getpreferredencoding(False)) +9 10 | io.TextIOWrapper(io.FileIO("test.txt")) +10 11 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 12 | tempfile.NamedTemporaryFile("w") + +unspecified_encoding.py:9:1: PLW1514 [*] `io.TextIOWrapper` without explicit `encoding` argument + | + 7 | # Errors. + 8 | open("test.txt") + 9 | io.TextIOWrapper(io.FileIO("test.txt")) + | ^^^^^^^^^^^^^^^^ PLW1514 +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 | tempfile.NamedTemporaryFile("w") + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +9 |-io.TextIOWrapper(io.FileIO("test.txt")) + 10 |+io.TextIOWrapper(io.FileIO("test.txt"), encoding=locale.getpreferredencoding(False)) +10 11 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 12 | tempfile.NamedTemporaryFile("w") +12 13 | tempfile.TemporaryFile("w") + +unspecified_encoding.py:10:1: PLW1514 [*] `io.TextIOWrapper` without explicit `encoding` argument + | + 8 | open("test.txt") + 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) + | ^^^^^^^^^^^^^^^^^^ PLW1514 +11 | tempfile.NamedTemporaryFile("w") +12 | tempfile.TemporaryFile("w") + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +9 10 | io.TextIOWrapper(io.FileIO("test.txt")) +10 |-hugo.TextIOWrapper(hugo.FileIO("test.txt")) + 11 |+hugo.TextIOWrapper(hugo.FileIO("test.txt"), encoding=locale.getpreferredencoding(False)) +11 12 | tempfile.NamedTemporaryFile("w") +12 13 | tempfile.TemporaryFile("w") +13 14 | codecs.open("test.txt") + +unspecified_encoding.py:11:1: PLW1514 [*] `tempfile.NamedTemporaryFile` in text mode without explicit `encoding` argument + | + 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 | tempfile.NamedTemporaryFile("w") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW1514 +12 | tempfile.TemporaryFile("w") +13 | codecs.open("test.txt") + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +9 10 | io.TextIOWrapper(io.FileIO("test.txt")) +10 11 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 |-tempfile.NamedTemporaryFile("w") + 12 |+tempfile.NamedTemporaryFile("w", encoding=locale.getpreferredencoding(False)) +12 13 | tempfile.TemporaryFile("w") +13 14 | codecs.open("test.txt") +14 15 | tempfile.SpooledTemporaryFile(0, "w") + +unspecified_encoding.py:12:1: PLW1514 [*] `tempfile.TemporaryFile` in text mode without explicit `encoding` argument + | +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 | tempfile.NamedTemporaryFile("w") +12 | tempfile.TemporaryFile("w") + | ^^^^^^^^^^^^^^^^^^^^^^ PLW1514 +13 | codecs.open("test.txt") +14 | tempfile.SpooledTemporaryFile(0, "w") + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +9 10 | io.TextIOWrapper(io.FileIO("test.txt")) +10 11 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 12 | tempfile.NamedTemporaryFile("w") +12 |-tempfile.TemporaryFile("w") + 13 |+tempfile.TemporaryFile("w", encoding=locale.getpreferredencoding(False)) +13 14 | codecs.open("test.txt") +14 15 | tempfile.SpooledTemporaryFile(0, "w") +15 16 | + +unspecified_encoding.py:13:1: PLW1514 [*] `codecs.open` in text mode without explicit `encoding` argument + | +11 | tempfile.NamedTemporaryFile("w") +12 | tempfile.TemporaryFile("w") +13 | codecs.open("test.txt") + | ^^^^^^^^^^^ PLW1514 +14 | tempfile.SpooledTemporaryFile(0, "w") + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +10 11 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 12 | tempfile.NamedTemporaryFile("w") +12 13 | tempfile.TemporaryFile("w") +13 |-codecs.open("test.txt") + 14 |+codecs.open("test.txt", encoding=locale.getpreferredencoding(False)) +14 15 | tempfile.SpooledTemporaryFile(0, "w") +15 16 | +16 17 | # Non-errors. + +unspecified_encoding.py:14:1: PLW1514 [*] `tempfile.SpooledTemporaryFile` in text mode without explicit `encoding` argument + | +12 | tempfile.TemporaryFile("w") +13 | codecs.open("test.txt") +14 | tempfile.SpooledTemporaryFile(0, "w") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW1514 +15 | +16 | # Non-errors. + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +11 12 | tempfile.NamedTemporaryFile("w") +12 13 | tempfile.TemporaryFile("w") +13 14 | codecs.open("test.txt") +14 |-tempfile.SpooledTemporaryFile(0, "w") + 15 |+tempfile.SpooledTemporaryFile(0, "w", encoding=locale.getpreferredencoding(False)) +15 16 | +16 17 | # Non-errors. +17 18 | open("test.txt", encoding="utf-8") + +unspecified_encoding.py:46:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +44 | tempfile.SpooledTemporaryFile(0, ) +45 | +46 | open("test.txt",) + | ^^^^ PLW1514 +47 | open() +48 | open( + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +43 44 | tempfile.SpooledTemporaryFile(0, "wb") +44 45 | tempfile.SpooledTemporaryFile(0, ) +45 46 | +46 |-open("test.txt",) + 47 |+open("test.txt", encoding=locale.getpreferredencoding(False),) +47 48 | open() +48 49 | open( +49 50 | "test.txt", # comment + +unspecified_encoding.py:47:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +46 | open("test.txt",) +47 | open() + | ^^^^ PLW1514 +48 | open( +49 | "test.txt", # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +44 45 | tempfile.SpooledTemporaryFile(0, ) +45 46 | +46 47 | open("test.txt",) +47 |-open() + 48 |+open(encoding=locale.getpreferredencoding(False)) +48 49 | open( +49 50 | "test.txt", # comment +50 51 | ) + +unspecified_encoding.py:48:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +46 | open("test.txt",) +47 | open() +48 | open( + | ^^^^ PLW1514 +49 | "test.txt", # comment +50 | ) + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +46 47 | open("test.txt",) +47 48 | open() +48 49 | open( +49 |- "test.txt", # comment + 50 |+ "test.txt", encoding=locale.getpreferredencoding(False), # comment +50 51 | ) +51 52 | open( +52 53 | "test.txt", + +unspecified_encoding.py:51:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +49 | "test.txt", # comment +50 | ) +51 | open( + | ^^^^ PLW1514 +52 | "test.txt", +53 | # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +49 50 | "test.txt", # comment +50 51 | ) +51 52 | open( +52 |- "test.txt", + 53 |+ "test.txt", encoding=locale.getpreferredencoding(False), +53 54 | # comment +54 55 | ) +55 56 | open(("test.txt"),) + +unspecified_encoding.py:55:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +53 | # comment +54 | ) +55 | open(("test.txt"),) + | ^^^^ PLW1514 +56 | open( +57 | ("test.txt"), # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +52 53 | "test.txt", +53 54 | # comment +54 55 | ) +55 |-open(("test.txt"),) + 56 |+open(("test.txt"), encoding=locale.getpreferredencoding(False),) +56 57 | open( +57 58 | ("test.txt"), # comment +58 59 | ) + +unspecified_encoding.py:56:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +54 | ) +55 | open(("test.txt"),) +56 | open( + | ^^^^ PLW1514 +57 | ("test.txt"), # comment +58 | ) + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +54 55 | ) +55 56 | open(("test.txt"),) +56 57 | open( +57 |- ("test.txt"), # comment + 58 |+ ("test.txt"), encoding=locale.getpreferredencoding(False), # comment +58 59 | ) +59 60 | open( +60 61 | ("test.txt"), + +unspecified_encoding.py:59:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +57 | ("test.txt"), # comment +58 | ) +59 | open( + | ^^^^ PLW1514 +60 | ("test.txt"), +61 | # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +57 58 | ("test.txt"), # comment +58 59 | ) +59 60 | open( +60 |- ("test.txt"), + 61 |+ ("test.txt"), encoding=locale.getpreferredencoding(False), +61 62 | # comment +62 63 | ) +63 64 | + +unspecified_encoding.py:64:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +62 | ) +63 | +64 | open((("test.txt")),) + | ^^^^ PLW1514 +65 | open( +66 | (("test.txt")), # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +61 62 | # comment +62 63 | ) +63 64 | +64 |-open((("test.txt")),) + 65 |+open((("test.txt")), encoding=locale.getpreferredencoding(False),) +65 66 | open( +66 67 | (("test.txt")), # comment +67 68 | ) + +unspecified_encoding.py:65:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +64 | open((("test.txt")),) +65 | open( + | ^^^^ PLW1514 +66 | (("test.txt")), # comment +67 | ) + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +63 64 | +64 65 | open((("test.txt")),) +65 66 | open( +66 |- (("test.txt")), # comment + 67 |+ (("test.txt")), encoding=locale.getpreferredencoding(False), # comment +67 68 | ) +68 69 | open( +69 70 | (("test.txt")), + +unspecified_encoding.py:68:1: PLW1514 [*] `open` in text mode without explicit `encoding` argument + | +66 | (("test.txt")), # comment +67 | ) +68 | open( + | ^^^^ PLW1514 +69 | (("test.txt")), +70 | # comment + | + = help: Add explicit `encoding` argument + +ℹ Unsafe fix +3 3 | import tempfile +4 4 | import io as hugo +5 5 | import codecs + 6 |+import locale +6 7 | +7 8 | # Errors. +8 9 | open("test.txt") +-------------------------------------------------------------------------------- +66 67 | (("test.txt")), # comment +67 68 | ) +68 69 | open( +69 |- (("test.txt")), + 70 |+ (("test.txt")), encoding=locale.getpreferredencoding(False), +70 71 | # comment +71 72 | ) + + diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs index 161b63bfa2f77..dcc6a01ab64c8 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs @@ -185,13 +185,13 @@ fn create_fields_from_fields_arg(fields: &Expr) -> Option> { return None; } let ast::ExprStringLiteral { value: field, .. } = field.as_string_literal_expr()?; - if !is_identifier(field) { + if !is_identifier(field.to_str()) { return None; } - if is_dunder(field) { + if is_dunder(field.to_str()) { return None; } - Some(create_field_assignment_stmt(field, annotation)) + Some(create_field_assignment_stmt(field.to_str(), annotation)) }) .collect() } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs index dd5503ce22631..4f98f6e5fa365 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs @@ -174,13 +174,13 @@ fn fields_from_dict_literal(keys: &[Option], values: &[Expr]) -> Option { - if !is_identifier(field) { + if !is_identifier(field.to_str()) { return None; } - if is_dunder(field) { + if is_dunder(field.to_str()) { return None; } - Some(create_field_assignment_stmt(field, value)) + Some(create_field_assignment_stmt(field.to_str(), value)) } _ => None, }) diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs index 4828c46ebd270..fe151f4e459d9 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::{self as ast, Expr}; +use ruff_python_ast::{self as ast, Expr, LiteralExpressionRef}; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; @@ -52,20 +52,24 @@ impl LiteralType { } } -impl TryFrom<&Expr> for LiteralType { +impl TryFrom> for LiteralType { type Error = (); - fn try_from(expr: &Expr) -> Result { - match expr { - Expr::StringLiteral(_) => Ok(LiteralType::Str), - Expr::BytesLiteral(_) => Ok(LiteralType::Bytes), - Expr::NumberLiteral(ast::ExprNumberLiteral { value, .. }) => match value { - ast::Number::Int(_) => Ok(LiteralType::Int), - ast::Number::Float(_) => Ok(LiteralType::Float), - ast::Number::Complex { .. } => Err(()), - }, - Expr::BooleanLiteral(_) => Ok(LiteralType::Bool), - _ => Err(()), + fn try_from(literal_expr: LiteralExpressionRef<'_>) -> Result { + match literal_expr { + LiteralExpressionRef::StringLiteral(_) => Ok(LiteralType::Str), + LiteralExpressionRef::BytesLiteral(_) => Ok(LiteralType::Bytes), + LiteralExpressionRef::NumberLiteral(ast::ExprNumberLiteral { value, .. }) => { + match value { + ast::Number::Int(_) => Ok(LiteralType::Int), + ast::Number::Float(_) => Ok(LiteralType::Float), + ast::Number::Complex { .. } => Err(()), + } + } + LiteralExpressionRef::BooleanLiteral(_) => Ok(LiteralType::Bool), + LiteralExpressionRef::NoneLiteral(_) | LiteralExpressionRef::EllipsisLiteral(_) => { + Err(()) + } } } } @@ -194,12 +198,16 @@ pub(crate) fn native_literals( checker.diagnostics.push(diagnostic); } Some(arg) => { + let Some(literal_expr) = arg.as_literal_expr() else { + return; + }; + // Skip implicit string concatenations. - if arg.is_implicit_concatenated_string() { + if literal_expr.is_implicit_concatenated() { return; } - let Ok(arg_literal_type) = LiteralType::try_from(arg) else { + let Ok(arg_literal_type) = LiteralType::try_from(literal_expr) else { return; }; diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs index 3c757820d9078..4a340e3369699 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs @@ -228,14 +228,14 @@ fn clean_params_dictionary(right: &Expr, locator: &Locator, stylist: &Stylist) - }) = key { // If the dictionary key is not a valid variable name, abort. - if !is_identifier(key_string) { + if !is_identifier(key_string.to_str()) { return None; } // If there are multiple entries of the same key, abort. - if seen.contains(&key_string.as_str()) { + if seen.contains(&key_string.to_str()) { return None; } - seen.push(key_string); + seen.push(key_string.to_str()); if is_multi_line { if indent.is_none() { indent = indentation(locator, key); @@ -490,18 +490,10 @@ pub(crate) fn printf_string_formatting(checker: &mut Checker, expr: &Expr, right contents.push_str(&format!(".format{params_string}")); let mut diagnostic = Diagnostic::new(PrintfStringFormatting, expr.range()); - // Avoid fix if there are comments within the right-hand side: - // ``` - // "%s" % ( - // 0, # 0 - // ) - // ``` - if !checker.indexer().comment_ranges().intersects(right.range()) { - diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( - contents, - expr.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + contents, + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs index 549b340a76127..2e9d63766e65b 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs @@ -76,7 +76,7 @@ pub(crate) fn redundant_open_modes(checker: &mut Checker, call: &ast::ExprCall) .. }) = &keyword.value { - if let Ok(mode) = OpenMode::from_str(mode_param_value) { + if let Ok(mode) = OpenMode::from_str(mode_param_value.to_str()) { checker.diagnostics.push(create_check( call, &keyword.value, @@ -91,7 +91,7 @@ pub(crate) fn redundant_open_modes(checker: &mut Checker, call: &ast::ExprCall) } Some(mode_param) => { if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = &mode_param { - if let Ok(mode) = OpenMode::from_str(value) { + if let Ok(mode) = OpenMode::from_str(value.to_str()) { checker.diagnostics.push(create_check( call, mode_param, diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unicode_kind_prefix.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unicode_kind_prefix.rs index 481bd9548253c..60c09586a6aa5 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unicode_kind_prefix.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unicode_kind_prefix.rs @@ -1,11 +1,10 @@ use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; - -use ruff_python_parser::lexer::LexResult; -use ruff_python_parser::{StringKind, Tok}; - +use ruff_python_ast::StringLiteral; use ruff_text_size::{Ranged, TextRange, TextSize}; +use crate::checkers::ast::Checker; + /// ## What it does /// Checks for uses of the Unicode kind prefix (`u`) in strings. /// @@ -40,19 +39,13 @@ impl AlwaysFixableViolation for UnicodeKindPrefix { } /// UP025 -pub(crate) fn unicode_kind_prefix(diagnostics: &mut Vec, tokens: &[LexResult]) { - for (token, range) in tokens.iter().flatten() { - if let Tok::String { - kind: StringKind::Unicode, - .. - } = token - { - let mut diagnostic = Diagnostic::new(UnicodeKindPrefix, *range); - diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(TextRange::at( - range.start(), - TextSize::from(1), - )))); - diagnostics.push(diagnostic); - } +pub(crate) fn unicode_kind_prefix(checker: &mut Checker, string: &StringLiteral) { + if string.unicode { + let mut diagnostic = Diagnostic::new(UnicodeKindPrefix, string.range); + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(TextRange::at( + string.start(), + TextSize::from(1), + )))); + checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs index 5966624d9e661..4bb5dd82fb041 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs @@ -74,7 +74,7 @@ fn match_encoded_variable(func: &Expr) -> Option<&Expr> { fn is_utf8_encoding_arg(arg: &Expr) -> bool { if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = &arg { - UTF8_LITERALS.contains(&value.to_lowercase().as_str()) + UTF8_LITERALS.contains(&value.to_str().to_lowercase().as_str()) } else { false } @@ -161,7 +161,7 @@ pub(crate) fn unnecessary_encode_utf8(checker: &mut Checker, call: &ast::ExprCal Expr::StringLiteral(ast::ExprStringLiteral { value: literal, .. }) => { // Ex) `"str".encode()`, `"str".encode("utf-8")` if let Some(encoding_arg) = match_encoding_arg(&call.arguments) { - if literal.is_ascii() { + if literal.to_str().is_ascii() { // Ex) Convert `"foo".encode()` to `b"foo"`. let mut diagnostic = Diagnostic::new( UnnecessaryEncodeUTF8 { diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep585_annotation.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep585_annotation.rs index 3b91cd6504a0b..36e10b0a1c1f6 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep585_annotation.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep585_annotation.rs @@ -1,6 +1,6 @@ use ruff_python_ast::Expr; -use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::compose_call_path; use ruff_python_semantic::analyze::typing::ModuleMember; @@ -8,6 +8,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; +use crate::settings::types::PythonVersion; /// ## What it does /// Checks for the use of generics that can be replaced with standard library @@ -43,6 +44,11 @@ use crate::importer::ImportRequest; /// foo: list[int] = [1, 2, 3] /// ``` /// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may lead to runtime errors when +/// alongside libraries that rely on runtime type annotations, like Pydantic, +/// on Python versions prior to Python 3.9. +/// /// ## Options /// - `target-version` /// - `pyupgrade.keep-runtime-typing` @@ -90,10 +96,18 @@ pub(crate) fn use_pep585_annotation( ModuleMember::BuiltIn(name) => { // Built-in type, like `list`. if checker.semantic().is_builtin(name) { - diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( - (*name).to_string(), - expr.range(), - ))); + diagnostic.set_fix(Fix::applicable_edit( + Edit::range_replacement((*name).to_string(), expr.range()), + if checker.settings.preview.is_enabled() { + if checker.settings.target_version >= PythonVersion::Py310 { + Applicability::Safe + } else { + Applicability::Unsafe + } + } else { + Applicability::Safe + }, + )); } } ModuleMember::Member(module, member) => { @@ -105,7 +119,19 @@ pub(crate) fn use_pep585_annotation( checker.semantic(), )?; let reference_edit = Edit::range_replacement(binding, expr.range()); - Ok(Fix::unsafe_edits(import_edit, [reference_edit])) + Ok(Fix::applicable_edits( + import_edit, + [reference_edit], + if checker.settings.preview.is_enabled() { + if checker.settings.target_version >= PythonVersion::Py310 { + Applicability::Safe + } else { + Applicability::Unsafe + } + } else { + Applicability::Unsafe + }, + )) }); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs index cb8a9600dccfa..5332be054f86b 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::{pep_604_optional, pep_604_union}; use ruff_python_ast::{self as ast, Expr}; @@ -7,6 +7,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::fix::edits::pad; +use crate::settings::types::PythonVersion; /// ## What it does /// Check for type annotations that can be rewritten based on [PEP 604] syntax. @@ -36,6 +37,11 @@ use crate::fix::edits::pad; /// foo: int | str = 1 /// ``` /// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as it may lead to runtime errors when +/// alongside libraries that rely on runtime type annotations, like Pydantic, +/// on Python versions prior to Python 3.10. +/// /// ## Options /// - `target-version` /// - `pyupgrade.keep-runtime-typing` @@ -70,6 +76,16 @@ pub(crate) fn use_pep604_annotation( && !checker.semantic().in_complex_string_type_definition() && is_allowed_value(slice); + let applicability = if checker.settings.preview.is_enabled() { + if checker.settings.target_version >= PythonVersion::Py310 { + Applicability::Safe + } else { + Applicability::Unsafe + } + } else { + Applicability::Unsafe + }; + match operator { Pep604Operator::Optional => { let mut diagnostic = Diagnostic::new(NonPEP604Annotation, expr.range()); @@ -79,14 +95,17 @@ pub(crate) fn use_pep604_annotation( // Invalid type annotation. } _ => { - diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( - pad( - checker.generator().expr(&pep_604_optional(slice)), + diagnostic.set_fix(Fix::applicable_edit( + Edit::range_replacement( + pad( + checker.generator().expr(&pep_604_optional(slice)), + expr.range(), + checker.locator(), + ), expr.range(), - checker.locator(), ), - expr.range(), - ))); + applicability, + )); } } } @@ -100,25 +119,31 @@ pub(crate) fn use_pep604_annotation( // Invalid type annotation. } Expr::Tuple(ast::ExprTuple { elts, .. }) => { - diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( - pad( - checker.generator().expr(&pep_604_union(elts)), + diagnostic.set_fix(Fix::applicable_edit( + Edit::range_replacement( + pad( + checker.generator().expr(&pep_604_union(elts)), + expr.range(), + checker.locator(), + ), expr.range(), - checker.locator(), ), - expr.range(), - ))); + applicability, + )); } _ => { // Single argument. - diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( - pad( - checker.locator().slice(slice).to_string(), + diagnostic.set_fix(Fix::applicable_edit( + Edit::range_replacement( + pad( + checker.locator().slice(slice).to_string(), + expr.range(), + checker.locator(), + ), expr.range(), - checker.locator(), ), - expr.range(), - ))); + applicability, + )); } } } @@ -155,7 +180,6 @@ fn is_allowed_value(expr: &Expr) -> bool { | Expr::GeneratorExp(_) | Expr::Compare(_) | Expr::Call(_) - | Expr::FormattedValue(_) | Expr::FString(_) | Expr::StringLiteral(_) | Expr::BytesLiteral(_) diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP031_0.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP031_0.py.snap index a06ca5060c82b..fd5827fcfa413 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP031_0.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP031_0.py.snap @@ -896,7 +896,7 @@ UP031_0.py:104:5: UP031 [*] Use format specifiers instead of percent format 109 108 | 110 109 | "%s" % ( -UP031_0.py:110:1: UP031 Use format specifiers instead of percent format +UP031_0.py:110:1: UP031 [*] Use format specifiers instead of percent format | 108 | ) 109 | @@ -907,4 +907,36 @@ UP031_0.py:110:1: UP031 Use format specifiers instead of percent format | = help: Replace with format specifiers +ℹ Unsafe fix +107 107 | % (x,) +108 108 | ) +109 109 | +110 |-"%s" % ( + 110 |+"{}".format( +111 111 | x, # comment +112 112 | ) +113 113 | + +UP031_0.py:115:8: UP031 [*] Use format specifiers instead of percent format + | +115 | path = "%s-%s-%s.pem" % ( + | ________^ +116 | | safe_domain_name(cn), # common name, which should be filename safe because it is IDNA-encoded, but in case of a malformed cert make sure it's ok to use as a filename +117 | | cert.not_valid_after.date().isoformat().replace("-", ""), # expiration date +118 | | hexlify(cert.fingerprint(hashes.SHA256())).decode("ascii")[0:8], # fingerprint prefix +119 | | ) + | |_^ UP031 + | + = help: Replace with format specifiers + +ℹ Unsafe fix +112 112 | ) +113 113 | +114 114 | +115 |-path = "%s-%s-%s.pem" % ( + 115 |+path = "{}-{}-{}.pem".format( +116 116 | safe_domain_name(cn), # common name, which should be filename safe because it is IDNA-encoded, but in case of a malformed cert make sure it's ok to use as a filename +117 117 | cert.not_valid_after.date().isoformat().replace("-", ""), # expiration date +118 118 | hexlify(cert.fingerprint(hashes.SHA256())).decode("ascii")[0:8], # fingerprint prefix + diff --git a/crates/ruff_linter/src/rules/refurb/mod.rs b/crates/ruff_linter/src/rules/refurb/mod.rs index 49a2c49bfe6c2..d27985762cef4 100644 --- a/crates/ruff_linter/src/rules/refurb/mod.rs +++ b/crates/ruff_linter/src/rules/refurb/mod.rs @@ -28,6 +28,8 @@ mod tests { #[test_case(Rule::SingleItemMembershipTest, Path::new("FURB171.py"))] #[test_case(Rule::IsinstanceTypeNone, Path::new("FURB168.py"))] #[test_case(Rule::TypeNoneComparison, Path::new("FURB169.py"))] + #[test_case(Rule::RedundantLogBase, Path::new("FURB163.py"))] + #[test_case(Rule::HashlibDigestHex, Path::new("FURB181.py"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/refurb/rules/delete_full_slice.rs b/crates/ruff_linter/src/rules/refurb/rules/delete_full_slice.rs index a6584201fcfca..1b0e610bdbe54 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/delete_full_slice.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/delete_full_slice.rs @@ -14,7 +14,7 @@ use crate::rules::refurb::helpers::generate_method_call; /// dictionary. /// /// ## Why is this bad? -/// It's is faster and more succinct to remove all items via the `clear()` +/// It is faster and more succinct to remove all items via the `clear()` /// method. /// /// ## Known problems diff --git a/crates/ruff_linter/src/rules/refurb/rules/hashlib_digest_hex.rs b/crates/ruff_linter/src/rules/refurb/rules/hashlib_digest_hex.rs new file mode 100644 index 0000000000000..b8c7adf7cc833 --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/rules/hashlib_digest_hex.rs @@ -0,0 +1,120 @@ +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{Expr, ExprAttribute, ExprCall}; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for the use of `.digest().hex()` on a hashlib hash, like `sha512`. +/// +/// ## Why is this bad? +/// When generating a hex digest from a hash, it's preferable to use the +/// `.hexdigest()` method, rather than calling `.digest()` and then `.hex()`, +/// as the former is more concise and readable. +/// +/// ## Example +/// ```python +/// from hashlib import sha512 +/// +/// hashed = sha512(b"some data").digest().hex() +/// ``` +/// +/// Use instead: +/// ```python +/// from hashlib import sha512 +/// +/// hashed = sha512(b"some data").hexdigest() +/// ``` +/// +/// ## Fix safety +/// This rule's fix is marked as unsafe, as the target of the `.digest()` call +/// could be a user-defined class that implements a `.hex()` method, rather +/// than a hashlib hash object. +/// +/// ## References +/// - [Python documentation: `hashlib`](https://docs.python.org/3/library/hashlib.html) +#[violation] +pub struct HashlibDigestHex; + +impl Violation for HashlibDigestHex { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + + #[derive_message_formats] + fn message(&self) -> String { + format!("Use of hashlib's `.digest().hex()`") + } + + fn fix_title(&self) -> Option { + Some("Replace with `.hexdigest()`".to_string()) + } +} + +/// FURB181 +pub(crate) fn hashlib_digest_hex(checker: &mut Checker, call: &ExprCall) { + if !call.arguments.is_empty() { + return; + } + + let Expr::Attribute(ExprAttribute { attr, value, .. }) = call.func.as_ref() else { + return; + }; + + if attr.as_str() != "hex" { + return; + } + + let Expr::Call(ExprCall { + func, arguments, .. + }) = value.as_ref() + else { + return; + }; + + let Expr::Attribute(ExprAttribute { attr, value, .. }) = func.as_ref() else { + return; + }; + + if attr.as_str() != "digest" { + return; + } + + let Expr::Call(ExprCall { func, .. }) = value.as_ref() else { + return; + }; + + if checker.semantic().resolve_call_path(func).is_some_and( + |call_path: smallvec::SmallVec<[&str; 8]>| { + matches!( + call_path.as_slice(), + [ + "hashlib", + "md5" + | "sha1" + | "sha224" + | "sha256" + | "sha384" + | "sha512" + | "blake2b" + | "blake2s" + | "sha3_224" + | "sha3_256" + | "sha3_384" + | "sha3_512" + | "shake_128" + | "shake_256" + | "_Hash" + ] + ) + }, + ) { + let mut diagnostic = Diagnostic::new(HashlibDigestHex, call.range()); + if arguments.is_empty() { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + ".hexdigest".to_string(), + TextRange::new(value.end(), call.func.end()), + ))); + } + checker.diagnostics.push(diagnostic); + } +} diff --git a/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs b/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs index 3b14b62b78009..8b24c361ab200 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs @@ -66,7 +66,7 @@ pub(crate) fn no_implicit_cwd(checker: &mut Checker, call: &ExprCall) { let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = arg else { return; }; - if !matches!(value.as_str(), "" | ".") { + if !matches!(value.to_str(), "" | ".") { return; } } diff --git a/crates/ruff_linter/src/rules/refurb/rules/math_constant.rs b/crates/ruff_linter/src/rules/refurb/rules/math_constant.rs index 6b590275a38ba..23ef1aa8c1d21 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/math_constant.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/math_constant.rs @@ -53,23 +53,17 @@ pub(crate) fn math_constant(checker: &mut Checker, literal: &ast::ExprNumberLite let Number::Float(value) = literal.value else { return; }; - for (real_value, constant) in [ - (std::f64::consts::PI, "pi"), - (std::f64::consts::E, "e"), - (std::f64::consts::TAU, "tau"), - ] { - if (value - real_value).abs() < 1e-2 { - let mut diagnostic = Diagnostic::new( - MathConstant { - literal: checker.locator().slice(literal).into(), - constant, - }, - literal.range(), - ); - diagnostic.try_set_fix(|| convert_to_constant(literal, constant, checker)); - checker.diagnostics.push(diagnostic); - return; - } + + if let Some(constant) = Constant::from_value(value) { + let mut diagnostic = Diagnostic::new( + MathConstant { + literal: checker.locator().slice(literal).into(), + constant: constant.name(), + }, + literal.range(), + ); + diagnostic.try_set_fix(|| convert_to_constant(literal, constant.name(), checker)); + checker.diagnostics.push(diagnostic); } } @@ -88,3 +82,33 @@ fn convert_to_constant( [edit], )) } + +#[derive(Debug, Clone, Copy)] +enum Constant { + Pi, + E, + Tau, +} + +impl Constant { + #[allow(clippy::approx_constant)] + fn from_value(value: f64) -> Option { + if (3.14..3.15).contains(&value) { + Some(Self::Pi) + } else if (2.71..2.72).contains(&value) { + Some(Self::E) + } else if (6.28..6.29).contains(&value) { + Some(Self::Tau) + } else { + None + } + } + + fn name(self) -> &'static str { + match self { + Constant::Pi => "pi", + Constant::E => "e", + Constant::Tau => "tau", + } + } +} diff --git a/crates/ruff_linter/src/rules/refurb/rules/mod.rs b/crates/ruff_linter/src/rules/refurb/rules/mod.rs index 6729202272905..4f165af3b36e5 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/mod.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/mod.rs @@ -1,11 +1,13 @@ pub(crate) use check_and_remove_from_set::*; pub(crate) use delete_full_slice::*; +pub(crate) use hashlib_digest_hex::*; pub(crate) use if_expr_min_max::*; pub(crate) use implicit_cwd::*; pub(crate) use isinstance_type_none::*; pub(crate) use math_constant::*; pub(crate) use print_empty_string::*; pub(crate) use read_whole_file::*; +pub(crate) use redundant_log_base::*; pub(crate) use reimplemented_starmap::*; pub(crate) use repeated_append::*; pub(crate) use single_item_membership_test::*; @@ -15,12 +17,14 @@ pub(crate) use unnecessary_enumerate::*; mod check_and_remove_from_set; mod delete_full_slice; +mod hashlib_digest_hex; mod if_expr_min_max; mod implicit_cwd; mod isinstance_type_none; mod math_constant; mod print_empty_string; mod read_whole_file; +mod redundant_log_base; mod reimplemented_starmap; mod repeated_append; mod single_item_membership_test; diff --git a/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs b/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs index b71306c3444ae..8bf1e6b6bccfb 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs @@ -244,15 +244,11 @@ fn match_open_keywords( /// Match open mode to see if it is supported. fn match_open_mode(mode: &Expr) -> Option { - let ast::ExprStringLiteral { - value, - implicit_concatenated: false, - .. - } = mode.as_string_literal_expr()? - else { + let ast::ExprStringLiteral { value, .. } = mode.as_string_literal_expr()?; + if value.is_implicit_concatenated() { return None; - }; - match value.as_str() { + } + match value.to_str() { "r" => Some(ReadMode::Text), "rb" => Some(ReadMode::Bytes), _ => None, diff --git a/crates/ruff_linter/src/rules/refurb/rules/redundant_log_base.rs b/crates/ruff_linter/src/rules/refurb/rules/redundant_log_base.rs new file mode 100644 index 0000000000000..c7d6837d75699 --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/rules/redundant_log_base.rs @@ -0,0 +1,152 @@ +use anyhow::Result; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr, Number}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; +use crate::importer::ImportRequest; + +/// ## What it does +/// Checks for `math.log` calls with a redundant base. +/// +/// ## Why is this bad? +/// The default base of `math.log` is `e`, so specifying it explicitly is +/// redundant. +/// +/// Instead of passing 2 or 10 as the base, use `math.log2` or `math.log10` +/// respectively, as these dedicated variants are typically more accurate +/// than `math.log`. +/// +/// ## Example +/// ```python +/// import math +/// +/// math.log(4, math.e) +/// math.log(4, 2) +/// math.log(4, 10) +/// ``` +/// +/// Use instead: +/// ```python +/// import math +/// +/// math.log(4) +/// math.log2(4) +/// math.log10(4) +/// ``` +/// +/// ## References +/// - [Python documentation: `math.log`](https://docs.python.org/3/library/math.html#math.log) +/// - [Python documentation: `math.log2`](https://docs.python.org/3/library/math.html#math.log2) +/// - [Python documentation: `math.log10`](https://docs.python.org/3/library/math.html#math.log10) +/// - [Python documentation: `math.e`](https://docs.python.org/3/library/math.html#math.e) +#[violation] +pub struct RedundantLogBase { + base: Base, + arg: String, +} + +impl Violation for RedundantLogBase { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + + #[derive_message_formats] + fn message(&self) -> String { + let RedundantLogBase { base, arg } = self; + let log_function = base.to_log_function(); + format!("Prefer `math.{log_function}({arg})` over `math.log` with a redundant base") + } + + fn fix_title(&self) -> Option { + let RedundantLogBase { base, arg } = self; + let log_function = base.to_log_function(); + Some(format!("Replace with `math.{log_function}({arg})`")) + } +} + +/// FURB163 +pub(crate) fn redundant_log_base(checker: &mut Checker, call: &ast::ExprCall) { + if !call.arguments.keywords.is_empty() { + return; + } + + let [arg, base] = &call.arguments.args.as_slice() else { + return; + }; + + if !checker + .semantic() + .resolve_call_path(&call.func) + .as_ref() + .is_some_and(|call_path| matches!(call_path.as_slice(), ["math", "log"])) + { + return; + } + + let base = if is_number_literal(base, 2) { + Base::Two + } else if is_number_literal(base, 10) { + Base::Ten + } else if checker + .semantic() + .resolve_call_path(base) + .as_ref() + .is_some_and(|call_path| matches!(call_path.as_slice(), ["math", "e"])) + { + Base::E + } else { + return; + }; + + let mut diagnostic = Diagnostic::new( + RedundantLogBase { + base, + arg: checker.locator().slice(arg).into(), + }, + call.range(), + ); + diagnostic.try_set_fix(|| generate_fix(checker, call, base, arg)); + checker.diagnostics.push(diagnostic); +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Base { + E, + Two, + Ten, +} + +impl Base { + fn to_log_function(self) -> &'static str { + match self { + Base::E => "log", + Base::Two => "log2", + Base::Ten => "log10", + } + } +} + +fn is_number_literal(expr: &Expr, value: i8) -> bool { + if let Expr::NumberLiteral(number_literal) = expr { + if let Number::Int(number) = &number_literal.value { + return number.as_i8().is_some_and(|number| number == value); + } else if let Number::Float(number) = number_literal.value { + #[allow(clippy::float_cmp)] + return number == f64::from(value); + } + } + false +} + +fn generate_fix(checker: &Checker, call: &ast::ExprCall, base: Base, arg: &Expr) -> Result { + let (edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import("math", base.to_log_function()), + call.start(), + checker.semantic(), + )?; + let number = checker.locator().slice(arg); + Ok(Fix::safe_edits( + Edit::range_replacement(format!("{binding}({number})"), call.range()), + [edit], + )) +} diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB152_FURB152.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB152_FURB152.py.snap index aa97aead864cb..094f30df73e58 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB152_FURB152.py.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB152_FURB152.py.snap @@ -43,6 +43,7 @@ FURB152.py:5:5: FURB152 [*] Replace `6.28` with `math.tau` 6 |+C = math.tau * r # FURB152 6 7 | 7 8 | e = 2.71 # FURB152 +8 9 | FURB152.py:7:5: FURB152 [*] Replace `2.71` with `math.e` | @@ -50,6 +51,8 @@ FURB152.py:7:5: FURB152 [*] Replace `2.71` with `math.e` 6 | 7 | e = 2.71 # FURB152 | ^^^^ FURB152 +8 | +9 | r = 3.15 # OK | = help: Use `math.e` @@ -63,5 +66,59 @@ FURB152.py:7:5: FURB152 [*] Replace `2.71` with `math.e` 6 7 | 7 |-e = 2.71 # FURB152 8 |+e = math.e # FURB152 +8 9 | +9 10 | r = 3.15 # OK +10 11 | + +FURB152.py:11:5: FURB152 [*] Replace `3.141` with `math.pi` + | + 9 | r = 3.15 # OK +10 | +11 | r = 3.141 # FURB152 + | ^^^^^ FURB152 +12 | +13 | r = 3.1415 # FURB152 + | + = help: Use `math.pi` + +ℹ Safe fix + 1 |+import math +1 2 | r = 3.1 # OK +2 3 | +3 4 | A = 3.14 * r ** 2 # FURB152 +-------------------------------------------------------------------------------- +8 9 | +9 10 | r = 3.15 # OK +10 11 | +11 |-r = 3.141 # FURB152 + 12 |+r = math.pi # FURB152 +12 13 | +13 14 | r = 3.1415 # FURB152 +14 15 | + +FURB152.py:13:5: FURB152 [*] Replace `3.1415` with `math.pi` + | +11 | r = 3.141 # FURB152 +12 | +13 | r = 3.1415 # FURB152 + | ^^^^^^ FURB152 +14 | +15 | e = 2.7 # OK + | + = help: Use `math.pi` + +ℹ Safe fix + 1 |+import math +1 2 | r = 3.1 # OK +2 3 | +3 4 | A = 3.14 * r ** 2 # FURB152 +-------------------------------------------------------------------------------- +10 11 | +11 12 | r = 3.141 # FURB152 +12 13 | +13 |-r = 3.1415 # FURB152 + 14 |+r = math.pi # FURB152 +14 15 | +15 16 | e = 2.7 # OK diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB163_FURB163.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB163_FURB163.py.snap new file mode 100644 index 0000000000000..aeb83174daee1 --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB163_FURB163.py.snap @@ -0,0 +1,275 @@ +--- +source: crates/ruff_linter/src/rules/refurb/mod.rs +--- +FURB163.py:7:1: FURB163 [*] Prefer `math.log2(1)` over `math.log` with a redundant base + | +6 | # Errors. +7 | math.log(1, 2) + | ^^^^^^^^^^^^^^ FURB163 +8 | math.log(1, 10) +9 | math.log(1, math.e) + | + = help: Replace with `math.log2(1)` + +ℹ Safe fix +4 4 | from math import log as special_log +5 5 | +6 6 | # Errors. +7 |-math.log(1, 2) + 7 |+math.log2(1) +8 8 | math.log(1, 10) +9 9 | math.log(1, math.e) +10 10 | foo = ... + +FURB163.py:8:1: FURB163 [*] Prefer `math.log10(1)` over `math.log` with a redundant base + | + 6 | # Errors. + 7 | math.log(1, 2) + 8 | math.log(1, 10) + | ^^^^^^^^^^^^^^^ FURB163 + 9 | math.log(1, math.e) +10 | foo = ... + | + = help: Replace with `math.log10(1)` + +ℹ Safe fix +5 5 | +6 6 | # Errors. +7 7 | math.log(1, 2) +8 |-math.log(1, 10) + 8 |+math.log10(1) +9 9 | math.log(1, math.e) +10 10 | foo = ... +11 11 | math.log(foo, 2) + +FURB163.py:9:1: FURB163 [*] Prefer `math.log(1)` over `math.log` with a redundant base + | + 7 | math.log(1, 2) + 8 | math.log(1, 10) + 9 | math.log(1, math.e) + | ^^^^^^^^^^^^^^^^^^^ FURB163 +10 | foo = ... +11 | math.log(foo, 2) + | + = help: Replace with `math.log(1)` + +ℹ Safe fix +6 6 | # Errors. +7 7 | math.log(1, 2) +8 8 | math.log(1, 10) +9 |-math.log(1, math.e) + 9 |+math.log(1) +10 10 | foo = ... +11 11 | math.log(foo, 2) +12 12 | math.log(foo, 10) + +FURB163.py:11:1: FURB163 [*] Prefer `math.log2(foo)` over `math.log` with a redundant base + | + 9 | math.log(1, math.e) +10 | foo = ... +11 | math.log(foo, 2) + | ^^^^^^^^^^^^^^^^ FURB163 +12 | math.log(foo, 10) +13 | math.log(foo, math.e) + | + = help: Replace with `math.log2(foo)` + +ℹ Safe fix +8 8 | math.log(1, 10) +9 9 | math.log(1, math.e) +10 10 | foo = ... +11 |-math.log(foo, 2) + 11 |+math.log2(foo) +12 12 | math.log(foo, 10) +13 13 | math.log(foo, math.e) +14 14 | math.log(1, special_e) + +FURB163.py:12:1: FURB163 [*] Prefer `math.log10(foo)` over `math.log` with a redundant base + | +10 | foo = ... +11 | math.log(foo, 2) +12 | math.log(foo, 10) + | ^^^^^^^^^^^^^^^^^ FURB163 +13 | math.log(foo, math.e) +14 | math.log(1, special_e) + | + = help: Replace with `math.log10(foo)` + +ℹ Safe fix +9 9 | math.log(1, math.e) +10 10 | foo = ... +11 11 | math.log(foo, 2) +12 |-math.log(foo, 10) + 12 |+math.log10(foo) +13 13 | math.log(foo, math.e) +14 14 | math.log(1, special_e) +15 15 | special_log(1, 2) + +FURB163.py:13:1: FURB163 [*] Prefer `math.log(foo)` over `math.log` with a redundant base + | +11 | math.log(foo, 2) +12 | math.log(foo, 10) +13 | math.log(foo, math.e) + | ^^^^^^^^^^^^^^^^^^^^^ FURB163 +14 | math.log(1, special_e) +15 | special_log(1, 2) + | + = help: Replace with `math.log(foo)` + +ℹ Safe fix +10 10 | foo = ... +11 11 | math.log(foo, 2) +12 12 | math.log(foo, 10) +13 |-math.log(foo, math.e) + 13 |+math.log(foo) +14 14 | math.log(1, special_e) +15 15 | special_log(1, 2) +16 16 | special_log(1, 10) + +FURB163.py:14:1: FURB163 [*] Prefer `math.log(1)` over `math.log` with a redundant base + | +12 | math.log(foo, 10) +13 | math.log(foo, math.e) +14 | math.log(1, special_e) + | ^^^^^^^^^^^^^^^^^^^^^^ FURB163 +15 | special_log(1, 2) +16 | special_log(1, 10) + | + = help: Replace with `math.log(1)` + +ℹ Safe fix +11 11 | math.log(foo, 2) +12 12 | math.log(foo, 10) +13 13 | math.log(foo, math.e) +14 |-math.log(1, special_e) + 14 |+math.log(1) +15 15 | special_log(1, 2) +16 16 | special_log(1, 10) +17 17 | special_log(1, math.e) + +FURB163.py:15:1: FURB163 [*] Prefer `math.log2(1)` over `math.log` with a redundant base + | +13 | math.log(foo, math.e) +14 | math.log(1, special_e) +15 | special_log(1, 2) + | ^^^^^^^^^^^^^^^^^ FURB163 +16 | special_log(1, 10) +17 | special_log(1, math.e) + | + = help: Replace with `math.log2(1)` + +ℹ Safe fix +12 12 | math.log(foo, 10) +13 13 | math.log(foo, math.e) +14 14 | math.log(1, special_e) +15 |-special_log(1, 2) + 15 |+math.log2(1) +16 16 | special_log(1, 10) +17 17 | special_log(1, math.e) +18 18 | special_log(1, special_e) + +FURB163.py:16:1: FURB163 [*] Prefer `math.log10(1)` over `math.log` with a redundant base + | +14 | math.log(1, special_e) +15 | special_log(1, 2) +16 | special_log(1, 10) + | ^^^^^^^^^^^^^^^^^^ FURB163 +17 | special_log(1, math.e) +18 | special_log(1, special_e) + | + = help: Replace with `math.log10(1)` + +ℹ Safe fix +13 13 | math.log(foo, math.e) +14 14 | math.log(1, special_e) +15 15 | special_log(1, 2) +16 |-special_log(1, 10) + 16 |+math.log10(1) +17 17 | special_log(1, math.e) +18 18 | special_log(1, special_e) +19 19 | math.log(1, 2.0) + +FURB163.py:17:1: FURB163 [*] Prefer `math.log(1)` over `math.log` with a redundant base + | +15 | special_log(1, 2) +16 | special_log(1, 10) +17 | special_log(1, math.e) + | ^^^^^^^^^^^^^^^^^^^^^^ FURB163 +18 | special_log(1, special_e) +19 | math.log(1, 2.0) + | + = help: Replace with `math.log(1)` + +ℹ Safe fix +14 14 | math.log(1, special_e) +15 15 | special_log(1, 2) +16 16 | special_log(1, 10) +17 |-special_log(1, math.e) + 17 |+math.log(1) +18 18 | special_log(1, special_e) +19 19 | math.log(1, 2.0) +20 20 | math.log(1, 10.0) + +FURB163.py:18:1: FURB163 [*] Prefer `math.log(1)` over `math.log` with a redundant base + | +16 | special_log(1, 10) +17 | special_log(1, math.e) +18 | special_log(1, special_e) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ FURB163 +19 | math.log(1, 2.0) +20 | math.log(1, 10.0) + | + = help: Replace with `math.log(1)` + +ℹ Safe fix +15 15 | special_log(1, 2) +16 16 | special_log(1, 10) +17 17 | special_log(1, math.e) +18 |-special_log(1, special_e) + 18 |+math.log(1) +19 19 | math.log(1, 2.0) +20 20 | math.log(1, 10.0) +21 21 | + +FURB163.py:19:1: FURB163 [*] Prefer `math.log2(1)` over `math.log` with a redundant base + | +17 | special_log(1, math.e) +18 | special_log(1, special_e) +19 | math.log(1, 2.0) + | ^^^^^^^^^^^^^^^^ FURB163 +20 | math.log(1, 10.0) + | + = help: Replace with `math.log2(1)` + +ℹ Safe fix +16 16 | special_log(1, 10) +17 17 | special_log(1, math.e) +18 18 | special_log(1, special_e) +19 |-math.log(1, 2.0) + 19 |+math.log2(1) +20 20 | math.log(1, 10.0) +21 21 | +22 22 | # Ok. + +FURB163.py:20:1: FURB163 [*] Prefer `math.log10(1)` over `math.log` with a redundant base + | +18 | special_log(1, special_e) +19 | math.log(1, 2.0) +20 | math.log(1, 10.0) + | ^^^^^^^^^^^^^^^^^ FURB163 +21 | +22 | # Ok. + | + = help: Replace with `math.log10(1)` + +ℹ Safe fix +17 17 | special_log(1, math.e) +18 18 | special_log(1, special_e) +19 19 | math.log(1, 2.0) +20 |-math.log(1, 10.0) + 20 |+math.log10(1) +21 21 | +22 22 | # Ok. +23 23 | math.log2(1) + + diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB181_FURB181.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB181_FURB181.py.snap new file mode 100644 index 0000000000000..cca7645c90adf --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB181_FURB181.py.snap @@ -0,0 +1,339 @@ +--- +source: crates/ruff_linter/src/rules/refurb/mod.rs +--- +FURB181.py:19:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +17 | # these will match +18 | +19 | blake2b().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +20 | blake2s().digest().hex() +21 | md5().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +16 16 | +17 17 | # these will match +18 18 | +19 |-blake2b().digest().hex() + 19 |+blake2b().hexdigest() +20 20 | blake2s().digest().hex() +21 21 | md5().digest().hex() +22 22 | sha1().digest().hex() + +FURB181.py:20:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +19 | blake2b().digest().hex() +20 | blake2s().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +21 | md5().digest().hex() +22 | sha1().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +17 17 | # these will match +18 18 | +19 19 | blake2b().digest().hex() +20 |-blake2s().digest().hex() + 20 |+blake2s().hexdigest() +21 21 | md5().digest().hex() +22 22 | sha1().digest().hex() +23 23 | sha224().digest().hex() + +FURB181.py:21:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +19 | blake2b().digest().hex() +20 | blake2s().digest().hex() +21 | md5().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^ FURB181 +22 | sha1().digest().hex() +23 | sha224().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +18 18 | +19 19 | blake2b().digest().hex() +20 20 | blake2s().digest().hex() +21 |-md5().digest().hex() + 21 |+md5().hexdigest() +22 22 | sha1().digest().hex() +23 23 | sha224().digest().hex() +24 24 | sha256().digest().hex() + +FURB181.py:22:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +20 | blake2s().digest().hex() +21 | md5().digest().hex() +22 | sha1().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^ FURB181 +23 | sha224().digest().hex() +24 | sha256().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +19 19 | blake2b().digest().hex() +20 20 | blake2s().digest().hex() +21 21 | md5().digest().hex() +22 |-sha1().digest().hex() + 22 |+sha1().hexdigest() +23 23 | sha224().digest().hex() +24 24 | sha256().digest().hex() +25 25 | sha384().digest().hex() + +FURB181.py:23:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +21 | md5().digest().hex() +22 | sha1().digest().hex() +23 | sha224().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +24 | sha256().digest().hex() +25 | sha384().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +20 20 | blake2s().digest().hex() +21 21 | md5().digest().hex() +22 22 | sha1().digest().hex() +23 |-sha224().digest().hex() + 23 |+sha224().hexdigest() +24 24 | sha256().digest().hex() +25 25 | sha384().digest().hex() +26 26 | sha3_224().digest().hex() + +FURB181.py:24:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +22 | sha1().digest().hex() +23 | sha224().digest().hex() +24 | sha256().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +25 | sha384().digest().hex() +26 | sha3_224().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +21 21 | md5().digest().hex() +22 22 | sha1().digest().hex() +23 23 | sha224().digest().hex() +24 |-sha256().digest().hex() + 24 |+sha256().hexdigest() +25 25 | sha384().digest().hex() +26 26 | sha3_224().digest().hex() +27 27 | sha3_256().digest().hex() + +FURB181.py:25:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +23 | sha224().digest().hex() +24 | sha256().digest().hex() +25 | sha384().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +26 | sha3_224().digest().hex() +27 | sha3_256().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +22 22 | sha1().digest().hex() +23 23 | sha224().digest().hex() +24 24 | sha256().digest().hex() +25 |-sha384().digest().hex() + 25 |+sha384().hexdigest() +26 26 | sha3_224().digest().hex() +27 27 | sha3_256().digest().hex() +28 28 | sha3_384().digest().hex() + +FURB181.py:26:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +24 | sha256().digest().hex() +25 | sha384().digest().hex() +26 | sha3_224().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +27 | sha3_256().digest().hex() +28 | sha3_384().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +23 23 | sha224().digest().hex() +24 24 | sha256().digest().hex() +25 25 | sha384().digest().hex() +26 |-sha3_224().digest().hex() + 26 |+sha3_224().hexdigest() +27 27 | sha3_256().digest().hex() +28 28 | sha3_384().digest().hex() +29 29 | sha3_512().digest().hex() + +FURB181.py:27:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +25 | sha384().digest().hex() +26 | sha3_224().digest().hex() +27 | sha3_256().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +28 | sha3_384().digest().hex() +29 | sha3_512().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +24 24 | sha256().digest().hex() +25 25 | sha384().digest().hex() +26 26 | sha3_224().digest().hex() +27 |-sha3_256().digest().hex() + 27 |+sha3_256().hexdigest() +28 28 | sha3_384().digest().hex() +29 29 | sha3_512().digest().hex() +30 30 | sha512().digest().hex() + +FURB181.py:28:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +26 | sha3_224().digest().hex() +27 | sha3_256().digest().hex() +28 | sha3_384().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +29 | sha3_512().digest().hex() +30 | sha512().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +25 25 | sha384().digest().hex() +26 26 | sha3_224().digest().hex() +27 27 | sha3_256().digest().hex() +28 |-sha3_384().digest().hex() + 28 |+sha3_384().hexdigest() +29 29 | sha3_512().digest().hex() +30 30 | sha512().digest().hex() +31 31 | shake_128().digest(10).hex() + +FURB181.py:29:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +27 | sha3_256().digest().hex() +28 | sha3_384().digest().hex() +29 | sha3_512().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +30 | sha512().digest().hex() +31 | shake_128().digest(10).hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +26 26 | sha3_224().digest().hex() +27 27 | sha3_256().digest().hex() +28 28 | sha3_384().digest().hex() +29 |-sha3_512().digest().hex() + 29 |+sha3_512().hexdigest() +30 30 | sha512().digest().hex() +31 31 | shake_128().digest(10).hex() +32 32 | shake_256().digest(10).hex() + +FURB181.py:30:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +28 | sha3_384().digest().hex() +29 | sha3_512().digest().hex() +30 | sha512().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +31 | shake_128().digest(10).hex() +32 | shake_256().digest(10).hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +27 27 | sha3_256().digest().hex() +28 28 | sha3_384().digest().hex() +29 29 | sha3_512().digest().hex() +30 |-sha512().digest().hex() + 30 |+sha512().hexdigest() +31 31 | shake_128().digest(10).hex() +32 32 | shake_256().digest(10).hex() +33 33 | + +FURB181.py:31:1: FURB181 Use of hashlib's `.digest().hex()` + | +29 | sha3_512().digest().hex() +30 | sha512().digest().hex() +31 | shake_128().digest(10).hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +32 | shake_256().digest(10).hex() + | + = help: Replace with `.hexdigest()` + +FURB181.py:32:1: FURB181 Use of hashlib's `.digest().hex()` + | +30 | sha512().digest().hex() +31 | shake_128().digest(10).hex() +32 | shake_256().digest(10).hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +33 | +34 | hashlib.sha256().digest().hex() + | + = help: Replace with `.hexdigest()` + +FURB181.py:34:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +32 | shake_256().digest(10).hex() +33 | +34 | hashlib.sha256().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +35 | +36 | sha256(b"text").digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +31 31 | shake_128().digest(10).hex() +32 32 | shake_256().digest(10).hex() +33 33 | +34 |-hashlib.sha256().digest().hex() + 34 |+hashlib.sha256().hexdigest() +35 35 | +36 36 | sha256(b"text").digest().hex() +37 37 | + +FURB181.py:36:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +34 | hashlib.sha256().digest().hex() +35 | +36 | sha256(b"text").digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +37 | +38 | hash_algo().digest().hex() + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +33 33 | +34 34 | hashlib.sha256().digest().hex() +35 35 | +36 |-sha256(b"text").digest().hex() + 36 |+sha256(b"text").hexdigest() +37 37 | +38 38 | hash_algo().digest().hex() +39 39 | + +FURB181.py:38:1: FURB181 [*] Use of hashlib's `.digest().hex()` + | +36 | sha256(b"text").digest().hex() +37 | +38 | hash_algo().digest().hex() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB181 +39 | +40 | # not yet supported + | + = help: Replace with `.hexdigest()` + +ℹ Unsafe fix +35 35 | +36 36 | sha256(b"text").digest().hex() +37 37 | +38 |-hash_algo().digest().hex() + 38 |+hash_algo().hexdigest() +39 39 | +40 40 | # not yet supported +41 41 | h = sha256() + + diff --git a/crates/ruff_linter/src/rules/ruff/rules/asyncio_dangling_task.rs b/crates/ruff_linter/src/rules/ruff/rules/asyncio_dangling_task.rs index f6f03fc8d955e..2f339b95c35dd 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/asyncio_dangling_task.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/asyncio_dangling_task.rs @@ -1,14 +1,12 @@ use std::fmt; -use ruff_python_ast::{self as ast, Expr}; - +use ast::Stmt; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_semantic::analyze::typing; +use ruff_python_ast::{self as ast, Expr}; +use ruff_python_semantic::{analyze::typing, Binding, SemanticModel}; use ruff_text_size::Ranged; -use crate::checkers::ast::Checker; - /// ## What it does /// Checks for `asyncio.create_task` and `asyncio.ensure_future` calls /// that do not store a reference to the returned result. @@ -66,35 +64,34 @@ impl Violation for AsyncioDanglingTask { } /// RUF006 -pub(crate) fn asyncio_dangling_task(checker: &mut Checker, expr: &Expr) { +pub(crate) fn asyncio_dangling_task(expr: &Expr, semantic: &SemanticModel) -> Option { let Expr::Call(ast::ExprCall { func, .. }) = expr else { - return; + return None; }; // Ex) `asyncio.create_task(...)` - if let Some(method) = checker - .semantic() - .resolve_call_path(func) - .and_then(|call_path| match call_path.as_slice() { - ["asyncio", "create_task"] => Some(Method::CreateTask), - ["asyncio", "ensure_future"] => Some(Method::EnsureFuture), - _ => None, - }) + if let Some(method) = + semantic + .resolve_call_path(func) + .and_then(|call_path| match call_path.as_slice() { + ["asyncio", "create_task"] => Some(Method::CreateTask), + ["asyncio", "ensure_future"] => Some(Method::EnsureFuture), + _ => None, + }) { - checker.diagnostics.push(Diagnostic::new( + return Some(Diagnostic::new( AsyncioDanglingTask { method }, expr.range(), )); - return; } // Ex) `loop = asyncio.get_running_loop(); loop.create_task(...)` if let Expr::Attribute(ast::ExprAttribute { attr, value, .. }) = func.as_ref() { if attr == "create_task" { - if typing::resolve_assignment(value, checker.semantic()).is_some_and(|call_path| { + if typing::resolve_assignment(value, semantic).is_some_and(|call_path| { matches!(call_path.as_slice(), ["asyncio", "get_running_loop"]) }) { - checker.diagnostics.push(Diagnostic::new( + return Some(Diagnostic::new( AsyncioDanglingTask { method: Method::CreateTask, }, @@ -103,6 +100,28 @@ pub(crate) fn asyncio_dangling_task(checker: &mut Checker, expr: &Expr) { } } } + None +} + +/// RUF006 +pub(crate) fn asyncio_dangling_binding( + binding: &Binding, + semantic: &SemanticModel, +) -> Option { + if binding.is_used() || !binding.kind.is_assignment() { + return None; + } + + let source = binding.source?; + match semantic.statement(source) { + Stmt::Assign(ast::StmtAssign { value, targets, .. }) if targets.len() == 1 => { + asyncio_dangling_task(value, semantic) + } + Stmt::AnnAssign(ast::StmtAnnAssign { + value: Some(value), .. + }) => asyncio_dangling_task(value, semantic), + _ => None, + } } #[derive(Debug, PartialEq, Eq, Copy, Clone)] diff --git a/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs b/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs index 1931270157b1a..7fe11923d2222 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs @@ -1,7 +1,4 @@ use anyhow::{bail, Result}; -use libcst_native::{ - ConcatenatedString, Expression, FormattedStringContent, FormattedStringExpression, -}; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -11,7 +8,10 @@ use ruff_source_file::Locator; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::cst::matchers::{match_call_mut, match_name, transform_expression}; +use crate::cst::matchers::{ + match_call_mut, match_formatted_string, match_formatted_string_expression, match_name, + transform_expression, +}; /// ## What it does /// Checks for uses of `str()`, `repr()`, and `ascii()` as explicit type @@ -52,25 +52,16 @@ impl AlwaysFixableViolation for ExplicitFStringTypeConversion { } /// RUF010 -pub(crate) fn explicit_f_string_type_conversion( - checker: &mut Checker, - expr: &Expr, - values: &[Expr], -) { - for (index, formatted_value) in values - .iter() - .filter_map(|expr| { - if let Expr::FormattedValue(expr) = &expr { - Some(expr) - } else { - None - } - }) - .enumerate() - { - let ast::ExprFormattedValue { - value, conversion, .. - } = formatted_value; +pub(crate) fn explicit_f_string_type_conversion(checker: &mut Checker, f_string: &ast::FString) { + for (index, element) in f_string.elements.iter().enumerate() { + let Some(ast::FStringExpressionElement { + expression, + conversion, + .. + }) = element.as_expression() + else { + continue; + }; // Skip if there's already a conversion flag. if !conversion.is_none() { @@ -86,7 +77,7 @@ pub(crate) fn explicit_f_string_type_conversion( range: _, }, .. - }) = value.as_ref() + }) = expression.as_ref() else { continue; }; @@ -121,9 +112,9 @@ pub(crate) fn explicit_f_string_type_conversion( continue; } - let mut diagnostic = Diagnostic::new(ExplicitFStringTypeConversion, value.range()); + let mut diagnostic = Diagnostic::new(ExplicitFStringTypeConversion, expression.range()); diagnostic.try_set_fix(|| { - convert_call_to_conversion_flag(expr, index, checker.locator(), checker.stylist()) + convert_call_to_conversion_flag(f_string, index, checker.locator(), checker.stylist()) }); checker.diagnostics.push(diagnostic); } @@ -131,15 +122,17 @@ pub(crate) fn explicit_f_string_type_conversion( /// Generate a [`Fix`] to replace an explicit type conversion with a conversion flag. fn convert_call_to_conversion_flag( - expr: &Expr, + f_string: &ast::FString, index: usize, locator: &Locator, stylist: &Stylist, ) -> Result { - let source_code = locator.slice(expr); + let source_code = locator.slice(f_string); transform_expression(source_code, stylist, |mut expression| { + let formatted_string = match_formatted_string(&mut expression)?; // Replace the formatted call expression at `index` with a conversion flag. - let formatted_string_expression = match_part(index, &mut expression)?; + let formatted_string_expression = + match_formatted_string_expression(&mut formatted_string.parts[index])?; let call = match_call_mut(&mut formatted_string_expression.expression)?; let name = match_name(&call.func)?; match name.value { @@ -157,63 +150,5 @@ fn convert_call_to_conversion_flag( formatted_string_expression.expression = call.args[0].value.clone(); Ok(expression) }) - .map(|output| Fix::safe_edit(Edit::range_replacement(output, expr.range()))) -} - -/// Return the [`FormattedStringContent`] at the given index in an f-string or implicit -/// string concatenation. -fn match_part<'a, 'b>( - index: usize, - expr: &'a mut Expression<'b>, -) -> Result<&'a mut FormattedStringExpression<'b>> { - match expr { - Expression::ConcatenatedString(expr) => Ok(collect_parts(expr).remove(index)), - Expression::FormattedString(expr) => { - // Find the formatted expression at the given index. The `parts` field contains a mix - // of string literals and expressions, but our `index` only counts expressions. All - // the boxing and mutability makes this difficult to write in a functional style. - let mut format_index = 0; - for part in &mut expr.parts { - if let FormattedStringContent::Expression(expr) = part { - if format_index == index { - return Ok(expr); - } - format_index += 1; - } - } - - bail!("Index out of bounds: `{index}`") - } - _ => bail!("Unexpected expression: `{:?}`", expr), - } -} - -/// Given an implicit string concatenation, return a list of all the formatted expressions. -fn collect_parts<'a, 'b>( - expr: &'a mut ConcatenatedString<'b>, -) -> Vec<&'a mut FormattedStringExpression<'b>> { - fn inner<'a, 'b>( - string: &'a mut libcst_native::String<'b>, - formatted_expressions: &mut Vec<&'a mut FormattedStringExpression<'b>>, - ) { - match string { - libcst_native::String::Formatted(expr) => { - for part in &mut expr.parts { - if let FormattedStringContent::Expression(expr) = part { - formatted_expressions.push(expr); - } - } - } - libcst_native::String::Concatenated(expr) => { - inner(&mut expr.left, formatted_expressions); - inner(&mut expr.right, formatted_expressions); - } - libcst_native::String::Simple(_) => {} - } - } - - let mut formatted_expressions = vec![]; - inner(&mut expr.left, &mut formatted_expressions); - inner(&mut expr.right, &mut formatted_expressions); - formatted_expressions + .map(|output| Fix::safe_edit(Edit::range_replacement(output, f_string.range()))) } diff --git a/crates/ruff_linter/src/rules/ruff/rules/helpers.rs b/crates/ruff_linter/src/rules/ruff/rules/helpers.rs index 78caf8d18fb5d..6cf01db9db998 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/helpers.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/helpers.rs @@ -65,7 +65,9 @@ pub(super) fn has_default_copy_semantics( semantic.resolve_call_path(expr).is_some_and(|call_path| { matches!( call_path.as_slice(), - ["pydantic", "BaseModel" | "BaseSettings"] | ["msgspec", "Struct"] + ["pydantic", "BaseModel" | "BaseSettings"] + | ["pydantic_settings", "BaseSettings"] + | ["msgspec", "Struct"] ) }) }) diff --git a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs index db23de636b7a5..c9e3b06e0df04 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs @@ -181,15 +181,10 @@ pub(crate) fn implicit_optional(checker: &mut Checker, parameters: &Parameters) continue; }; - if let Expr::StringLiteral(ast::ExprStringLiteral { - range, - value: string, - .. - }) = annotation.as_ref() - { + if let Expr::StringLiteral(ast::ExprStringLiteral { range, value }) = annotation.as_ref() { // Quoted annotation. if let Ok((annotation, kind)) = - parse_type_annotation(string, *range, checker.locator().contents()) + parse_type_annotation(value.to_str(), *range, checker.locator().contents()) { let Some(expr) = type_hint_explicitly_allows_none( &annotation, diff --git a/crates/ruff_linter/src/rules/ruff/rules/mutable_class_default.rs b/crates/ruff_linter/src/rules/ruff/rules/mutable_class_default.rs index da1e2837512a4..776209d6f6812 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/mutable_class_default.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/mutable_class_default.rs @@ -20,13 +20,15 @@ use crate::rules::ruff::rules::helpers::{ /// changed in one instance, as those changes will unexpectedly affect all /// other instances. /// -/// When mutable value are intended, they should be annotated with -/// `typing.ClassVar`. +/// When mutable values are intended, they should be annotated with +/// `typing.ClassVar`. When mutability is not required, values should be +/// immutable types, like `tuple` or `frozenset`. /// /// ## Examples /// ```python /// class A: /// mutable_default: list[int] = [] +/// immutable_default: list[int] = [] /// ``` /// /// Use instead: @@ -36,6 +38,7 @@ use crate::rules::ruff::rules::helpers::{ /// /// class A: /// mutable_default: ClassVar[list[int]] = [] +/// immutable_default: tuple[int, ...] = () /// ``` #[violation] pub struct MutableClassDefault; diff --git a/crates/ruff_linter/src/rules/ruff/rules/snapshots/ruff_linter__rules__ruff__rules__unreachable__tests__for.py.md.snap b/crates/ruff_linter/src/rules/ruff/rules/snapshots/ruff_linter__rules__ruff__rules__unreachable__tests__for.py.md.snap index e93710e8eda53..6850c5f69b04b 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/snapshots/ruff_linter__rules__ruff__rules__unreachable__tests__for.py.md.snap +++ b/crates/ruff_linter/src/rules/ruff/rules/snapshots/ruff_linter__rules__ruff__rules__unreachable__tests__for.py.md.snap @@ -238,4 +238,65 @@ flowchart TD block0 --> return ``` +## Function 8 +### Source +```python +def func(): + for i in range(5): + pass + else: + return 1 +``` + +### Control Flow Graph +```mermaid +flowchart TD + start(("Start")) + return(("End")) + block0["pass\n"] + block1["return 1\n"] + block2["for i in range(5): + pass + else: + return 1\n"] + + start --> block2 + block2 -- "range(5)" --> block0 + block2 -- "else" --> block1 + block1 --> return + block0 --> return +``` + +## Function 9 +### Source +```python +def func(): + for i in range(5): + pass + else: + return 1 + x = 1 +``` + +### Control Flow Graph +```mermaid +flowchart TD + start(("Start")) + return(("End")) + block0["x = 1\n"] + block1["pass\n"] + block2["return 1\n"] + block3["for i in range(5): + pass + else: + return 1\n"] + + start --> block3 + block3 -- "range(5)" --> block1 + block3 -- "else" --> block2 + block2 --> return + block1 --> block3 + block0 --> return +``` + diff --git a/crates/ruff_linter/src/rules/ruff/rules/snapshots/ruff_linter__rules__ruff__rules__unreachable__tests__match.py.md.snap b/crates/ruff_linter/src/rules/ruff/rules/snapshots/ruff_linter__rules__ruff__rules__unreachable__tests__match.py.md.snap index 54cb336e95510..d74b08116f936 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/snapshots/ruff_linter__rules__ruff__rules__unreachable__tests__match.py.md.snap +++ b/crates/ruff_linter/src/rules/ruff/rules/snapshots/ruff_linter__rules__ruff__rules__unreachable__tests__match.py.md.snap @@ -773,4 +773,43 @@ flowchart TD block0 --> return ``` +## Function 14 +### Source +```python +def func(point): + match point: + case (0, 0): + print("Origin") + case foo: + raise ValueError("oops") +``` + +### Control Flow Graph +```mermaid +flowchart TD + start(("Start")) + return(("End")) + block0[["`*(empty)*`"]] + block1["raise ValueError(#quot;oops#quot;)\n"] + block2["match point: + case (0, 0): + print(#quot;Origin#quot;) + case foo: + raise ValueError(#quot;oops#quot;)\n"] + block3["print(#quot;Origin#quot;)\n"] + block4["match point: + case (0, 0): + print(#quot;Origin#quot;) + case foo: + raise ValueError(#quot;oops#quot;)\n"] + + start --> block4 + block4 -- "case (0, 0)" --> block3 + block4 -- "else" --> block2 + block3 --> block0 + block2 --> block1 + block1 --> return + block0 --> return +``` + diff --git a/crates/ruff_linter/src/rules/ruff/rules/unreachable.rs b/crates/ruff_linter/src/rules/ruff/rules/unreachable.rs index 8f5db5a35bc32..5445aabd3eea1 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/unreachable.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/unreachable.rs @@ -2,8 +2,8 @@ use std::{fmt, iter, usize}; use log::error; use ruff_python_ast::{ - Expr, ExprBooleanLiteral, Identifier, MatchCase, Pattern, PatternMatchAs, Stmt, StmtFor, - StmtMatch, StmtReturn, StmtTry, StmtWhile, StmtWith, + Expr, ExprBooleanLiteral, Identifier, MatchCase, Pattern, PatternMatchAs, PatternMatchOr, Stmt, + StmtFor, StmtMatch, StmtReturn, StmtTry, StmtWhile, StmtWith, }; use ruff_text_size::{Ranged, TextRange, TextSize}; @@ -416,13 +416,6 @@ fn match_case<'stmt>( } last_statement_index }; - // TODO: handle named arguments, e.g. - // ```python - // match $subject: - // case $binding: - // print($binding) - // ``` - // These should also return `NextBlock::Always`. let next = if is_wildcard(case) { // Wildcard case is always taken. NextBlock::Always(next_block_index) @@ -436,10 +429,25 @@ fn match_case<'stmt>( BasicBlock { stmts, next } } -/// Returns true if `pattern` is a wildcard (`_`) pattern. +/// Returns true if the [`MatchCase`] is a wildcard pattern. fn is_wildcard(pattern: &MatchCase) -> bool { - pattern.guard.is_none() - && matches!(&pattern.pattern, Pattern::MatchAs(PatternMatchAs { pattern, name, .. }) if pattern.is_none() && name.is_none()) + /// Returns true if the [`Pattern`] is a wildcard pattern. + fn is_wildcard_pattern(pattern: &Pattern) -> bool { + match pattern { + Pattern::MatchValue(_) + | Pattern::MatchSingleton(_) + | Pattern::MatchSequence(_) + | Pattern::MatchMapping(_) + | Pattern::MatchClass(_) + | Pattern::MatchStar(_) => false, + Pattern::MatchAs(PatternMatchAs { pattern, .. }) => pattern.is_none(), + Pattern::MatchOr(PatternMatchOr { patterns, .. }) => { + patterns.iter().all(is_wildcard_pattern) + } + } + } + + pattern.guard.is_none() && is_wildcard_pattern(&pattern.pattern) } #[derive(Debug, Default)] @@ -477,6 +485,8 @@ impl<'stmt> BasicBlocksBuilder<'stmt> { | Stmt::AugAssign(_) | Stmt::AnnAssign(_) | Stmt::Break(_) + | Stmt::TypeAlias(_) + | Stmt::IpyEscapeCommand(_) | Stmt::Pass(_) => self.unconditional_next_block(after), Stmt::Continue(_) => { // NOTE: the next branch gets fixed up in `change_next_block`. @@ -625,7 +635,6 @@ impl<'stmt> BasicBlocksBuilder<'stmt> { | Expr::Set(_) | Expr::Compare(_) | Expr::Call(_) - | Expr::FormattedValue(_) | Expr::FString(_) | Expr::StringLiteral(_) | Expr::BytesLiteral(_) @@ -638,6 +647,7 @@ impl<'stmt> BasicBlocksBuilder<'stmt> { | Expr::Starred(_) | Expr::Name(_) | Expr::List(_) + | Expr::IpyEscapeCommand(_) | Expr::Tuple(_) | Expr::Slice(_) => self.unconditional_next_block(after), // TODO: handle these expressions. @@ -651,13 +661,10 @@ impl<'stmt> BasicBlocksBuilder<'stmt> { | Expr::Await(_) | Expr::Yield(_) | Expr::YieldFrom(_) => self.unconditional_next_block(after), - Expr::IpyEscapeCommand(_) => todo!(), } } // The tough branches are done, here is an easy one. Stmt::Return(_) => NextBlock::Terminate, - Stmt::TypeAlias(_) => todo!(), - Stmt::IpyEscapeCommand(_) => todo!(), }; // Include any statements in the block that don't divert the control flow. @@ -890,6 +897,8 @@ fn needs_next_block(stmts: &[Stmt]) -> bool { | Stmt::AnnAssign(_) | Stmt::Expr(_) | Stmt::Pass(_) + | Stmt::TypeAlias(_) + | Stmt::IpyEscapeCommand(_) // TODO: check below. | Stmt::Break(_) | Stmt::Continue(_) @@ -899,8 +908,6 @@ fn needs_next_block(stmts: &[Stmt]) -> bool { | Stmt::Match(_) | Stmt::Try(_) | Stmt::Assert(_) => true, - Stmt::TypeAlias(_) => todo!(), - Stmt::IpyEscapeCommand(_) => todo!(), } } @@ -919,6 +926,8 @@ fn is_control_flow_stmt(stmt: &Stmt) -> bool { | Stmt::AugAssign(_) | Stmt::AnnAssign(_) | Stmt::Expr(_) + | Stmt::TypeAlias(_) + | Stmt::IpyEscapeCommand(_) | Stmt::Pass(_) => false, Stmt::Return(_) | Stmt::For(_) @@ -931,8 +940,6 @@ fn is_control_flow_stmt(stmt: &Stmt) -> bool { | Stmt::Assert(_) | Stmt::Break(_) | Stmt::Continue(_) => true, - Stmt::TypeAlias(_) => todo!(), - Stmt::IpyEscapeCommand(_) => todo!(), } } diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF006_RUF006.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF006_RUF006.py.snap index 11a0bababe525..def73e5a2e11e 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF006_RUF006.py.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF006_RUF006.py.snap @@ -17,11 +17,27 @@ RUF006.py:11:5: RUF006 Store a reference to the return value of `asyncio.ensure_ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006 | -RUF006.py:79:5: RUF006 Store a reference to the return value of `asyncio.create_task` +RUF006.py:68:12: RUF006 Store a reference to the return value of `asyncio.create_task` | -77 | def f(): -78 | loop = asyncio.get_running_loop() -79 | loop.create_task(coordinator.ws_connect()) # Error +66 | # Error +67 | def f(): +68 | task = asyncio.create_task(coordinator.ws_connect()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006 + | + +RUF006.py:74:26: RUF006 Store a reference to the return value of `asyncio.create_task` + | +72 | def f(): +73 | loop = asyncio.get_running_loop() +74 | task: asyncio.Task = loop.create_task(coordinator.ws_connect()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006 + | + +RUF006.py:97:5: RUF006 Store a reference to the return value of `asyncio.create_task` + | +95 | def f(): +96 | loop = asyncio.get_running_loop() +97 | loop.create_task(coordinator.ws_connect()) # Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF006 | diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap index 019c140aecbc9..5f38b489e2ab9 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap @@ -344,6 +344,7 @@ RUF100_3.py:23:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 23 |+print(a) # noqa: F821 # comment 24 24 | print(a) # noqa: E501, F821 comment 25 25 | print(a) # noqa: E501, F821 comment +26 26 | RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | @@ -362,6 +363,8 @@ RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 24 |-print(a) # noqa: E501, F821 comment 24 |+print(a) # noqa: F821 comment 25 25 | print(a) # noqa: E501, F821 comment +26 26 | +27 27 | print(a) # comment with unicode µ # noqa: E501 RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | @@ -369,6 +372,8 @@ RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 24 | print(a) # noqa: E501, F821 comment 25 | print(a) # noqa: E501, F821 comment | ^^^^^^^^^^^^^^^^^^ RUF100 +26 | +27 | print(a) # comment with unicode µ # noqa: E501 | = help: Remove unused `noqa` directive @@ -378,5 +383,50 @@ RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) 24 24 | print(a) # noqa: E501, F821 comment 25 |-print(a) # noqa: E501, F821 comment 25 |+print(a) # noqa: F821 comment +26 26 | +27 27 | print(a) # comment with unicode µ # noqa: E501 +28 28 | print(a) # comment with unicode µ # noqa: E501, F821 + +RUF100_3.py:27:7: F821 Undefined name `a` + | +25 | print(a) # noqa: E501, F821 comment +26 | +27 | print(a) # comment with unicode µ # noqa: E501 + | ^ F821 +28 | print(a) # comment with unicode µ # noqa: E501, F821 + | + +RUF100_3.py:27:39: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +25 | print(a) # noqa: E501, F821 comment +26 | +27 | print(a) # comment with unicode µ # noqa: E501 + | ^^^^^^^^^^^^ RUF100 +28 | print(a) # comment with unicode µ # noqa: E501, F821 + | + = help: Remove unused `noqa` directive + +ℹ Safe fix +24 24 | print(a) # noqa: E501, F821 comment +25 25 | print(a) # noqa: E501, F821 comment +26 26 | +27 |-print(a) # comment with unicode µ # noqa: E501 + 27 |+print(a) # comment with unicode µ +28 28 | print(a) # comment with unicode µ # noqa: E501, F821 + +RUF100_3.py:28:39: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +27 | print(a) # comment with unicode µ # noqa: E501 +28 | print(a) # comment with unicode µ # noqa: E501, F821 + | ^^^^^^^^^^^^^^^^^^ RUF100 + | + = help: Remove unused `noqa` directive + +ℹ Safe fix +25 25 | print(a) # noqa: E501, F821 comment +26 26 | +27 27 | print(a) # comment with unicode µ # noqa: E501 +28 |-print(a) # comment with unicode µ # noqa: E501, F821 + 28 |+print(a) # comment with unicode µ # noqa: F821 diff --git a/crates/ruff_linter/src/rules/ruff/typing.rs b/crates/ruff_linter/src/rules/ruff/typing.rs index 730e93357ef94..f01e89c3fd0c2 100644 --- a/crates/ruff_linter/src/rules/ruff/typing.rs +++ b/crates/ruff_linter/src/rules/ruff/typing.rs @@ -108,12 +108,10 @@ impl<'a> TypingTarget<'a> { .. }) => Some(TypingTarget::PEP604Union(left, right)), Expr::NoneLiteral(_) => Some(TypingTarget::None), - Expr::StringLiteral(ast::ExprStringLiteral { - value: string, - range, - .. - }) => parse_type_annotation(string, *range, locator.contents()) - .map_or(None, |(expr, _)| Some(TypingTarget::ForwardReference(expr))), + Expr::StringLiteral(ast::ExprStringLiteral { value, range }) => { + parse_type_annotation(value.to_str(), *range, locator.contents()) + .map_or(None, |(expr, _)| Some(TypingTarget::ForwardReference(expr))) + } _ => semantic.resolve_call_path(expr).map_or( // If we can't resolve the call path, it must be defined in the // same file, so we assume it's `Any` as it could be a type alias. diff --git a/crates/ruff_linter/src/rules/tryceratops/helpers.rs b/crates/ruff_linter/src/rules/tryceratops/helpers.rs index 0e707c1e3924e..bd12ddebfe93b 100644 --- a/crates/ruff_linter/src/rules/tryceratops/helpers.rs +++ b/crates/ruff_linter/src/rules/tryceratops/helpers.rs @@ -1,6 +1,6 @@ use ruff_python_ast::visitor; use ruff_python_ast::visitor::Visitor; -use ruff_python_ast::{self as ast, Expr}; +use ruff_python_ast::{self as ast, ExceptHandler, Expr}; use ruff_python_semantic::analyze::logging; use ruff_python_semantic::SemanticModel; use ruff_python_stdlib::logging::LoggingLevel; @@ -50,4 +50,9 @@ impl<'a, 'b> Visitor<'b> for LoggerCandidateVisitor<'a, 'b> { } visitor::walk_expr(self, expr); } + + fn visit_except_handler(&mut self, _except_handler: &'b ExceptHandler) { + // Don't recurse into exception handlers, since we'll re-run the visitor on any such + // handlers. + } } diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs b/crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs index fda19f79e8b58..d390dafda4492 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs @@ -23,7 +23,7 @@ use crate::rules::tryceratops::helpers::LoggerCandidateVisitor; /// import logging /// /// -/// def foo(): +/// def func(): /// try: /// raise NotImplementedError /// except NotImplementedError: @@ -35,10 +35,10 @@ use crate::rules::tryceratops::helpers::LoggerCandidateVisitor; /// import logging /// /// -/// def foo(): +/// def func(): /// try: /// raise NotImplementedError -/// except NotImplementedError as exc: +/// except NotImplementedError: /// logging.exception("Exception occurred") /// ``` /// diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/raise_vanilla_args.rs b/crates/ruff_linter/src/rules/tryceratops/rules/raise_vanilla_args.rs index 58f94a56e7bf3..b50d6fd7e7ef0 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/raise_vanilla_args.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/raise_vanilla_args.rs @@ -89,10 +89,25 @@ pub(crate) fn raise_vanilla_args(checker: &mut Checker, expr: &Expr) { /// some whitespace). fn contains_message(expr: &Expr) -> bool { match expr { - Expr::FString(ast::ExprFString { values, .. }) => { - for value in values { - if contains_message(value) { - return true; + Expr::FString(ast::ExprFString { value, .. }) => { + for f_string_part in value { + match f_string_part { + ast::FStringPart::Literal(literal) => { + if literal.chars().any(char::is_whitespace) { + return true; + } + } + ast::FStringPart::FString(f_string) => { + for literal in f_string + .elements + .iter() + .filter_map(|element| element.as_literal()) + { + if literal.chars().any(char::is_whitespace) { + return true; + } + } + } } } } diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs index 8b3fad0f082d9..701e9a575df6c 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs @@ -30,7 +30,7 @@ use crate::rules::tryceratops::helpers::LoggerCandidateVisitor; /// ```python /// try: /// ... -/// except ValueError as e: +/// except ValueError: /// logger.exception("Found an error") /// ``` #[violation] @@ -61,11 +61,7 @@ impl<'a> Visitor<'a> for NameVisitor<'a> { /// TRY401 pub(crate) fn verbose_log_message(checker: &mut Checker, handlers: &[ExceptHandler]) { for handler in handlers { - let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { name, body, .. }) = - handler; - let Some(target) = name else { - continue; - }; + let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) = handler; // Find all calls to `logging.exception`. let calls = { @@ -87,8 +83,14 @@ pub(crate) fn verbose_log_message(checker: &mut Checker, handlers: &[ExceptHandl } names }; + + // Find any bound exceptions in the call. for expr in names { - if expr.id == target.as_str() { + let Some(id) = checker.semantic().resolve_name(expr) else { + continue; + }; + let binding = checker.semantic().binding(id); + if binding.kind.is_bound_exception() { checker .diagnostics .push(Diagnostic::new(VerboseLogMessage, expr.range())); diff --git a/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap b/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap index 35b36493ec3a9..918fae360ea3a 100644 --- a/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap +++ b/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap @@ -86,4 +86,12 @@ TRY400.py:90:13: TRY400 Use `logging.exception` instead of `logging.error` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400 | +TRY400.py:121:13: TRY400 Use `logging.exception` instead of `logging.error` + | +119 | b = 2 +120 | except Exception: +121 | error("Context message here") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400 + | + diff --git a/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__verbose-log-message_TRY401.py.snap b/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__verbose-log-message_TRY401.py.snap index 3681b880d1f06..3f71c86e70cdc 100644 --- a/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__verbose-log-message_TRY401.py.snap +++ b/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__verbose-log-message_TRY401.py.snap @@ -177,4 +177,20 @@ TRY401.py:117:40: TRY401 Redundant exception object included in `logging.excepti | ^^ TRY401 | +TRY401.py:139:49: TRY401 Redundant exception object included in `logging.exception` call + | +137 | finish() +138 | except Exception as ex: +139 | logger.exception(f"Found an error: {ex}") # TRY401 + | ^^ TRY401 + | + +TRY401.py:150:49: TRY401 Redundant exception object included in `logging.exception` call + | +148 | finish() +149 | except Exception: +150 | logger.exception(f"Found an error: {ex}") # TRY401 + | ^^ TRY401 + | + diff --git a/crates/ruff_linter/src/settings/types.rs b/crates/ruff_linter/src/settings/types.rs index 8c8d84efb7f34..10bfb5189ebc2 100644 --- a/crates/ruff_linter/src/settings/types.rs +++ b/crates/ruff_linter/src/settings/types.rs @@ -119,16 +119,21 @@ impl From for PreviewMode { } } +/// Toggle for unsafe fixes. +/// `Hint` will not apply unsafe fixes but a message will be shown when they are available. +/// `Disabled` will not apply unsafe fixes or show a message. +/// `Enabled` will apply unsafe fixes. #[derive(Debug, Copy, Clone, CacheKey, Default, PartialEq, Eq, is_macro::Is)] pub enum UnsafeFixes { #[default] + Hint, Disabled, Enabled, } impl From for UnsafeFixes { - fn from(version: bool) -> Self { - if version { + fn from(value: bool) -> Self { + if value { UnsafeFixes::Enabled } else { UnsafeFixes::Disabled @@ -140,7 +145,7 @@ impl UnsafeFixes { pub fn required_applicability(&self) -> Applicability { match self { Self::Enabled => Applicability::Unsafe, - Self::Disabled => Applicability::Safe, + Self::Disabled | Self::Hint => Applicability::Safe, } } } @@ -418,6 +423,7 @@ pub enum SerializationFormat { Gitlab, Pylint, Azure, + Sarif, } impl Default for SerializationFormat { diff --git a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__ipy_escape_command.snap b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__ipy_escape_command.snap index 58aa72d7da26b..8c1a547e85966 100644 --- a/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__ipy_escape_command.snap +++ b/crates/ruff_linter/src/snapshots/ruff_linter__linter__tests__ipy_escape_command.snap @@ -19,5 +19,20 @@ ipy_escape_command.ipynb:cell 1:5:8: F401 [*] `os` imported but unused 5 |-import os 6 5 | 7 6 | _ = math.pi +8 7 | %%timeit + +ipy_escape_command.ipynb:cell 2:2:8: F401 [*] `sys` imported but unused + | +1 | %%timeit +2 | import sys + | ^^^ F401 + | + = help: Remove unused import: `sys` + +ℹ Safe fix +6 6 | +7 7 | _ = math.pi +8 8 | %%timeit +9 |-import sys diff --git a/crates/ruff_macros/src/newtype_index.rs b/crates/ruff_macros/src/newtype_index.rs index 2c1f6e14eca05..4ddc76c2e6838 100644 --- a/crates/ruff_macros/src/newtype_index.rs +++ b/crates/ruff_macros/src/newtype_index.rs @@ -45,6 +45,9 @@ pub(super) fn generate_newtype_index(item: ItemStruct) -> syn::Result syn::Result) -> fmt::Result { + match self { + SourceValue::String(string) => f.write_str(string), + SourceValue::StringArray(string_array) => { + for string in string_array { + f.write_str(string)?; + } + Ok(()) + } + } + } +} + +impl Cell { + /// Return the [`SourceValue`] of the cell. + pub(crate) fn source(&self) -> &SourceValue { + match self { + Cell::Code(cell) => &cell.source, + Cell::Markdown(cell) => &cell.source, + Cell::Raw(cell) => &cell.source, + } + } + + /// Update the [`SourceValue`] of the cell. + pub(crate) fn set_source(&mut self, source: SourceValue) { + match self { + Cell::Code(cell) => cell.source = source, + Cell::Markdown(cell) => cell.source = source, + Cell::Raw(cell) => cell.source = source, + } + } + + /// Return `true` if it's a valid code cell. + /// + /// A valid code cell is a cell where the cell type is [`Cell::Code`] and the + /// source doesn't contain a cell magic. + pub(crate) fn is_valid_code_cell(&self) -> bool { + let source = match self { + Cell::Code(cell) => &cell.source, + _ => return false, + }; + // Ignore cells containing cell magic as they act on the entire cell + // as compared to line magic which acts on a single line. + !match source { + SourceValue::String(string) => Self::is_magic_cell(string.lines()), + SourceValue::StringArray(string_array) => { + Self::is_magic_cell(string_array.iter().map(String::as_str)) + } + } + } + + /// Returns `true` if a cell should be ignored due to the use of cell magics. + fn is_magic_cell<'a>(lines: impl Iterator) -> bool { + let mut lines = lines.peekable(); + + // Detect automatic line magics (automagic), which aren't supported by the parser. If a line + // magic uses automagic, Jupyter doesn't allow following it with non-magic lines anyway, so + // we aren't missing out on any valid Python code. + // + // For example, this is valid: + // ```jupyter + // cat /path/to/file + // cat /path/to/file + // ``` + // + // But this is invalid: + // ```jupyter + // cat /path/to/file + // x = 1 + // ``` + // + // See: https://ipython.readthedocs.io/en/stable/interactive/magics.html + if lines + .peek() + .and_then(|line| line.split_whitespace().next()) + .is_some_and(|token| { + matches!( + token, + "alias" + | "alias_magic" + | "autoawait" + | "autocall" + | "automagic" + | "bookmark" + | "cd" + | "code_wrap" + | "colors" + | "conda" + | "config" + | "debug" + | "dhist" + | "dirs" + | "doctest_mode" + | "edit" + | "env" + | "gui" + | "history" + | "killbgscripts" + | "load" + | "load_ext" + | "loadpy" + | "logoff" + | "logon" + | "logstart" + | "logstate" + | "logstop" + | "lsmagic" + | "macro" + | "magic" + | "mamba" + | "matplotlib" + | "micromamba" + | "notebook" + | "page" + | "pastebin" + | "pdb" + | "pdef" + | "pdoc" + | "pfile" + | "pinfo" + | "pinfo2" + | "pip" + | "popd" + | "pprint" + | "precision" + | "prun" + | "psearch" + | "psource" + | "pushd" + | "pwd" + | "pycat" + | "pylab" + | "quickref" + | "recall" + | "rehashx" + | "reload_ext" + | "rerun" + | "reset" + | "reset_selective" + | "run" + | "save" + | "sc" + | "set_env" + | "sx" + | "system" + | "tb" + | "time" + | "timeit" + | "unalias" + | "unload_ext" + | "who" + | "who_ls" + | "whos" + | "xdel" + | "xmode" + ) + }) + { + return true; + } + + // Detect cell magics (which operate on multiple lines). + lines.any(|line| { + let Some(first) = line.split_whitespace().next() else { + return false; + }; + if first.len() < 2 { + return false; + } + let Some(command) = first.strip_prefix("%%") else { + return false; + }; + // These cell magics are special in that the lines following them are valid + // Python code and the variables defined in that scope are available to the + // rest of the notebook. + // + // For example: + // + // Cell 1: + // ```python + // x = 1 + // ``` + // + // Cell 2: + // ```python + // %%time + // y = x + // ``` + // + // Cell 3: + // ```python + // print(y) # Here, `y` is available. + // ``` + // + // This is to avoid false positives when these variables are referenced + // elsewhere in the notebook. + !matches!( + command, + "capture" | "debug" | "prun" | "pypy" | "python" | "python3" | "time" | "timeit" + ) + }) + } +} + +/// Cell offsets are used to keep track of the start and end offsets of each +/// cell in the concatenated source code. These offsets are in sorted order. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct CellOffsets(Vec); + +impl CellOffsets { + /// Create a new [`CellOffsets`] with the given capacity. + pub(crate) fn with_capacity(capacity: usize) -> Self { + Self(Vec::with_capacity(capacity)) + } + + /// Push a new offset to the end of the [`CellOffsets`]. + /// + /// # Panics + /// + /// Panics if the offset is less than the last offset pushed. + pub(crate) fn push(&mut self, offset: TextSize) { + if let Some(last_offset) = self.0.last() { + assert!( + *last_offset <= offset, + "Offsets must be pushed in sorted order" + ); + } + self.0.push(offset); + } + + /// Returns the range of the cell containing the given offset, if any. + pub fn containing_range(&self, offset: TextSize) -> Option { + self.iter().tuple_windows().find_map(|(start, end)| { + if *start <= offset && offset < *end { + Some(TextRange::new(*start, *end)) + } else { + None + } + }) + } + + /// Returns `true` if the given range contains a cell boundary. + pub fn has_cell_boundary(&self, range: TextRange) -> bool { + self.binary_search_by(|offset| { + if range.start() <= *offset { + if range.end() < *offset { + std::cmp::Ordering::Greater + } else { + std::cmp::Ordering::Equal + } + } else { + std::cmp::Ordering::Less + } + }) + .is_ok() + } +} + +impl Deref for CellOffsets { + type Target = [TextSize]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for CellOffsets { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/crates/ruff_notebook/src/lib.rs b/crates/ruff_notebook/src/lib.rs index 0d0bb5dc0a9e0..e95c483a2f5f0 100644 --- a/crates/ruff_notebook/src/lib.rs +++ b/crates/ruff_notebook/src/lib.rs @@ -1,9 +1,11 @@ //! Utils for reading and writing jupyter notebooks +pub use cell::*; pub use index::*; pub use notebook::*; pub use schema::*; +mod cell; mod index; mod notebook; mod schema; diff --git a/crates/ruff_notebook/src/notebook.rs b/crates/ruff_notebook/src/notebook.rs index 61994e7702648..ddc558ba21b87 100644 --- a/crates/ruff_notebook/src/notebook.rs +++ b/crates/ruff_notebook/src/notebook.rs @@ -1,5 +1,4 @@ use std::cmp::Ordering; -use std::fmt::Display; use std::fs::File; use std::io::{BufReader, Cursor, Read, Seek, SeekFrom, Write}; use std::path::Path; @@ -16,6 +15,7 @@ use ruff_diagnostics::{SourceMap, SourceMarker}; use ruff_source_file::{NewlineWithTrailingNewline, OneIndexed, UniversalNewlineIterator}; use ruff_text_size::TextSize; +use crate::cell::CellOffsets; use crate::index::NotebookIndex; use crate::schema::{Cell, RawNotebook, SortAlphabetically, SourceValue}; @@ -35,173 +35,6 @@ pub fn round_trip(path: &Path) -> anyhow::Result { Ok(String::from_utf8(writer)?) } -impl Display for SourceValue { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - SourceValue::String(string) => f.write_str(string), - SourceValue::StringArray(string_array) => { - for string in string_array { - f.write_str(string)?; - } - Ok(()) - } - } - } -} - -impl Cell { - /// Return the [`SourceValue`] of the cell. - fn source(&self) -> &SourceValue { - match self { - Cell::Code(cell) => &cell.source, - Cell::Markdown(cell) => &cell.source, - Cell::Raw(cell) => &cell.source, - } - } - - /// Update the [`SourceValue`] of the cell. - fn set_source(&mut self, source: SourceValue) { - match self { - Cell::Code(cell) => cell.source = source, - Cell::Markdown(cell) => cell.source = source, - Cell::Raw(cell) => cell.source = source, - } - } - - /// Return `true` if it's a valid code cell. - /// - /// A valid code cell is a cell where the cell type is [`Cell::Code`] and the - /// source doesn't contain a cell magic. - fn is_valid_code_cell(&self) -> bool { - let source = match self { - Cell::Code(cell) => &cell.source, - _ => return false, - }; - // Ignore cells containing cell magic as they act on the entire cell - // as compared to line magic which acts on a single line. - !match source { - SourceValue::String(string) => Self::is_magic_cell(string.lines()), - SourceValue::StringArray(string_array) => { - Self::is_magic_cell(string_array.iter().map(String::as_str)) - } - } - } - - /// Returns `true` if a cell should be ignored due to the use of cell magics. - fn is_magic_cell<'a>(lines: impl Iterator) -> bool { - let mut lines = lines.peekable(); - - // Detect automatic line magics (automagic), which aren't supported by the parser. If a line - // magic uses automagic, Jupyter doesn't allow following it with non-magic lines anyway, so - // we aren't missing out on any valid Python code. - // - // For example, this is valid: - // ```jupyter - // cat /path/to/file - // cat /path/to/file - // ``` - // - // But this is invalid: - // ```jupyter - // cat /path/to/file - // x = 1 - // ``` - // - // See: https://ipython.readthedocs.io/en/stable/interactive/magics.html - if lines - .peek() - .and_then(|line| line.split_whitespace().next()) - .is_some_and(|token| { - matches!( - token, - "alias" - | "alias_magic" - | "autoawait" - | "autocall" - | "automagic" - | "bookmark" - | "cd" - | "code_wrap" - | "colors" - | "conda" - | "config" - | "debug" - | "dhist" - | "dirs" - | "doctest_mode" - | "edit" - | "env" - | "gui" - | "history" - | "killbgscripts" - | "load" - | "load_ext" - | "loadpy" - | "logoff" - | "logon" - | "logstart" - | "logstate" - | "logstop" - | "lsmagic" - | "macro" - | "magic" - | "mamba" - | "matplotlib" - | "micromamba" - | "notebook" - | "page" - | "pastebin" - | "pdb" - | "pdef" - | "pdoc" - | "pfile" - | "pinfo" - | "pinfo2" - | "pip" - | "popd" - | "pprint" - | "precision" - | "prun" - | "psearch" - | "psource" - | "pushd" - | "pwd" - | "pycat" - | "pylab" - | "quickref" - | "recall" - | "rehashx" - | "reload_ext" - | "rerun" - | "reset" - | "reset_selective" - | "run" - | "save" - | "sc" - | "set_env" - | "sx" - | "system" - | "tb" - | "time" - | "timeit" - | "unalias" - | "unload_ext" - | "who" - | "who_ls" - | "whos" - | "xdel" - | "xmode" - ) - }) - { - return true; - } - - // Detect cell magics (which operate on multiple lines). - lines.any(|line| line.trim_start().starts_with("%%")) - } -} - /// An error that can occur while deserializing a Jupyter Notebook. #[derive(Error, Debug)] pub enum NotebookError { @@ -233,7 +66,7 @@ pub struct Notebook { raw: RawNotebook, /// The offsets of each cell in the concatenated source code. This includes /// the first and last character offsets as well. - cell_offsets: Vec, + cell_offsets: CellOffsets, /// The cell index of all valid code cells in the notebook. valid_code_cells: Vec, /// Flag to indicate if the JSON string of the notebook has a trailing newline. @@ -296,7 +129,7 @@ impl Notebook { let mut contents = Vec::with_capacity(valid_code_cells.len()); let mut current_offset = TextSize::from(0); - let mut cell_offsets = Vec::with_capacity(valid_code_cells.len()); + let mut cell_offsets = CellOffsets::with_capacity(valid_code_cells.len()); cell_offsets.push(TextSize::from(0)); for &idx in &valid_code_cells { @@ -492,9 +325,9 @@ impl Notebook { self.index.take().unwrap_or_else(|| self.build_index()) } - /// Return the cell offsets for the concatenated source code corresponding + /// Return the [`CellOffsets`] for the concatenated source code corresponding /// the Jupyter notebook. - pub fn cell_offsets(&self) -> &[TextSize] { + pub fn cell_offsets(&self) -> &CellOffsets { &self.cell_offsets } @@ -588,16 +421,18 @@ mod tests { )); } - #[test_case(Path::new("markdown.json"), false; "markdown")] - #[test_case(Path::new("only_magic.json"), true; "only_magic")] - #[test_case(Path::new("code_and_magic.json"), true; "code_and_magic")] - #[test_case(Path::new("only_code.json"), true; "only_code")] - #[test_case(Path::new("cell_magic.json"), false; "cell_magic")] - #[test_case(Path::new("automagic.json"), false; "automagic")] - #[test_case(Path::new("automagics.json"), false; "automagics")] - #[test_case(Path::new("automagic_before_code.json"), false; "automagic_before_code")] - #[test_case(Path::new("automagic_after_code.json"), true; "automagic_after_code")] - fn test_is_valid_code_cell(path: &Path, expected: bool) -> Result<()> { + #[test_case("markdown", false)] + #[test_case("only_magic", true)] + #[test_case("code_and_magic", true)] + #[test_case("only_code", true)] + #[test_case("cell_magic", false)] + #[test_case("valid_cell_magic", true)] + #[test_case("automagic", false)] + #[test_case("automagics", false)] + #[test_case("automagic_before_code", false)] + #[test_case("automagic_after_code", true)] + #[test_case("unicode_magic_gh9145", true)] + fn test_is_valid_code_cell(cell: &str, expected: bool) -> Result<()> { /// Read a Jupyter cell from the `resources/test/fixtures/jupyter/cell` directory. fn read_jupyter_cell(path: impl AsRef) -> Result { let path = notebook_path("cell").join(path); @@ -605,7 +440,10 @@ mod tests { Ok(serde_json::from_str(&source_code)?) } - assert_eq!(read_jupyter_cell(path)?.is_valid_code_cell(), expected); + assert_eq!( + read_jupyter_cell(format!("{cell}.json"))?.is_valid_code_cell(), + expected + ); Ok(()) } @@ -671,7 +509,7 @@ print("after empty cells") } ); assert_eq!( - notebook.cell_offsets(), + notebook.cell_offsets().as_ref(), &[ 0.into(), 90.into(), diff --git a/crates/ruff_python_ast/src/all.rs b/crates/ruff_python_ast/src/all.rs index 23472dafb61f9..b55858d66fe84 100644 --- a/crates/ruff_python_ast/src/all.rs +++ b/crates/ruff_python_ast/src/all.rs @@ -24,7 +24,7 @@ where fn add_to_names<'a>(elts: &'a [Expr], names: &mut Vec<&'a str>, flags: &mut DunderAllFlags) { for elt in elts { if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = elt { - names.push(value); + names.push(value.to_str()); } else { *flags |= DunderAllFlags::INVALID_OBJECT; } diff --git a/crates/ruff_python_ast/src/comparable.rs b/crates/ruff_python_ast/src/comparable.rs index 208b97d05505e..b3c7faf116a5c 100644 --- a/crates/ruff_python_ast/src/comparable.rs +++ b/crates/ruff_python_ast/src/comparable.rs @@ -509,6 +509,41 @@ impl<'a> From<&'a ast::ExceptHandler> for ComparableExceptHandler<'a> { } } +#[derive(Debug, PartialEq, Eq, Hash)] +pub enum ComparableFStringElement<'a> { + Literal(&'a str), + FStringExpressionElement(FStringExpressionElement<'a>), +} + +#[derive(Debug, PartialEq, Eq, Hash)] +pub struct FStringExpressionElement<'a> { + expression: ComparableExpr<'a>, + debug_text: Option<&'a ast::DebugText>, + conversion: ast::ConversionFlag, + format_spec: Option>>, +} + +impl<'a> From<&'a ast::FStringElement> for ComparableFStringElement<'a> { + fn from(fstring_element: &'a ast::FStringElement) -> Self { + match fstring_element { + ast::FStringElement::Literal(ast::FStringLiteralElement { value, .. }) => { + Self::Literal(value) + } + ast::FStringElement::Expression(formatted_value) => { + Self::FStringExpressionElement(FStringExpressionElement { + expression: (&formatted_value.expression).into(), + debug_text: formatted_value.debug_text.as_ref(), + conversion: formatted_value.conversion, + format_spec: formatted_value + .format_spec + .as_ref() + .map(|spec| spec.elements.iter().map(Into::into).collect()), + }) + } + } + } +} + #[derive(Debug, PartialEq, Eq, Hash)] pub struct ComparableElifElseClause<'a> { test: Option>, @@ -529,6 +564,91 @@ impl<'a> From<&'a ast::ElifElseClause> for ComparableElifElseClause<'a> { } } +#[derive(Debug, PartialEq, Eq, Hash)] +pub enum ComparableLiteral<'a> { + None, + Ellipsis, + Bool(&'a bool), + Str(Vec>), + Bytes(Vec>), + Number(ComparableNumber<'a>), +} + +impl<'a> From> for ComparableLiteral<'a> { + fn from(literal: ast::LiteralExpressionRef<'a>) -> Self { + match literal { + ast::LiteralExpressionRef::NoneLiteral(_) => Self::None, + ast::LiteralExpressionRef::EllipsisLiteral(_) => Self::Ellipsis, + ast::LiteralExpressionRef::BooleanLiteral(ast::ExprBooleanLiteral { + value, .. + }) => Self::Bool(value), + ast::LiteralExpressionRef::StringLiteral(ast::ExprStringLiteral { value, .. }) => { + Self::Str(value.iter().map(Into::into).collect()) + } + ast::LiteralExpressionRef::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => { + Self::Bytes(value.iter().map(Into::into).collect()) + } + ast::LiteralExpressionRef::NumberLiteral(ast::ExprNumberLiteral { value, .. }) => { + Self::Number(value.into()) + } + } + } +} + +#[derive(Debug, PartialEq, Eq, Hash)] +pub struct ComparableFString<'a> { + elements: Vec>, +} + +impl<'a> From<&'a ast::FString> for ComparableFString<'a> { + fn from(fstring: &'a ast::FString) -> Self { + Self { + elements: fstring.elements.iter().map(Into::into).collect(), + } + } +} + +#[derive(Debug, PartialEq, Eq, Hash)] +pub enum ComparableFStringPart<'a> { + Literal(ComparableStringLiteral<'a>), + FString(ComparableFString<'a>), +} + +impl<'a> From<&'a ast::FStringPart> for ComparableFStringPart<'a> { + fn from(f_string_part: &'a ast::FStringPart) -> Self { + match f_string_part { + ast::FStringPart::Literal(string_literal) => Self::Literal(string_literal.into()), + ast::FStringPart::FString(f_string) => Self::FString(f_string.into()), + } + } +} + +#[derive(Debug, PartialEq, Eq, Hash)] +pub struct ComparableStringLiteral<'a> { + value: &'a str, +} + +impl<'a> From<&'a ast::StringLiteral> for ComparableStringLiteral<'a> { + fn from(string_literal: &'a ast::StringLiteral) -> Self { + Self { + value: string_literal.value.as_str(), + } + } +} + +#[derive(Debug, PartialEq, Eq, Hash)] +pub struct ComparableBytesLiteral<'a> { + value: &'a [u8], +} + +impl<'a> From<&'a ast::BytesLiteral> for ComparableBytesLiteral<'a> { + fn from(bytes_literal: &'a ast::BytesLiteral) -> Self { + Self { + value: bytes_literal.value.as_slice(), + } + } +} + #[derive(Debug, PartialEq, Eq, Hash)] pub struct ExprBoolOp<'a> { op: ComparableBoolOp, @@ -632,57 +752,26 @@ pub struct ExprCall<'a> { } #[derive(Debug, PartialEq, Eq, Hash)] -pub struct ExprFormattedValue<'a> { +pub struct ExprFStringExpressionElement<'a> { value: Box>, debug_text: Option<&'a ast::DebugText>, conversion: ast::ConversionFlag, - format_spec: Option>>, + format_spec: Vec>, } #[derive(Debug, PartialEq, Eq, Hash)] pub struct ExprFString<'a> { - values: Vec>, -} - -#[derive(Debug, PartialEq, Eq, Hash)] -pub enum ComparableLiteral<'a> { - None, - Ellipsis, - Bool(&'a bool), - Str(&'a str), - Bytes(&'a [u8]), - Number(ComparableNumber<'a>), -} - -impl<'a> From> for ComparableLiteral<'a> { - fn from(literal: ast::LiteralExpressionRef<'a>) -> Self { - match literal { - ast::LiteralExpressionRef::NoneLiteral(_) => Self::None, - ast::LiteralExpressionRef::EllipsisLiteral(_) => Self::Ellipsis, - ast::LiteralExpressionRef::BooleanLiteral(ast::ExprBooleanLiteral { - value, .. - }) => Self::Bool(value), - ast::LiteralExpressionRef::StringLiteral(ast::ExprStringLiteral { value, .. }) => { - Self::Str(value) - } - ast::LiteralExpressionRef::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => { - Self::Bytes(value) - } - ast::LiteralExpressionRef::NumberLiteral(ast::ExprNumberLiteral { value, .. }) => { - Self::Number(value.into()) - } - } - } + parts: Vec>, } #[derive(Debug, PartialEq, Eq, Hash)] pub struct ExprStringLiteral<'a> { - value: &'a str, + parts: Vec>, } #[derive(Debug, PartialEq, Eq, Hash)] pub struct ExprBytesLiteral<'a> { - value: &'a [u8], + parts: Vec>, } #[derive(Debug, PartialEq, Eq, Hash)] @@ -759,14 +848,14 @@ pub enum ComparableExpr<'a> { YieldFrom(ExprYieldFrom<'a>), Compare(ExprCompare<'a>), Call(ExprCall<'a>), - FormattedValue(ExprFormattedValue<'a>), + FStringExpressionElement(ExprFStringExpressionElement<'a>), FString(ExprFString<'a>), StringLiteral(ExprStringLiteral<'a>), BytesLiteral(ExprBytesLiteral<'a>), NumberLiteral(ExprNumberLiteral<'a>), BoolLiteral(ExprBoolLiteral<'a>), NoneLiteral, - EllispsisLiteral, + EllipsisLiteral, Attribute(ExprAttribute<'a>), Subscript(ExprSubscript<'a>), Starred(ExprStarred<'a>), @@ -921,40 +1010,21 @@ impl<'a> From<&'a ast::Expr> for ComparableExpr<'a> { func: func.into(), arguments: arguments.into(), }), - ast::Expr::FormattedValue(ast::ExprFormattedValue { - value, - conversion, - debug_text, - format_spec, - range: _, - }) => Self::FormattedValue(ExprFormattedValue { - value: value.into(), - conversion: *conversion, - debug_text: debug_text.as_ref(), - format_spec: format_spec.as_ref().map(Into::into), - }), - ast::Expr::FString(ast::ExprFString { - values, - implicit_concatenated: _, - range: _, - }) => Self::FString(ExprFString { - values: values.iter().map(Into::into).collect(), - }), - ast::Expr::StringLiteral(ast::ExprStringLiteral { - value, - // Compare strings based on resolved value, not representation (i.e., ignore whether - // the string was implicitly concatenated). - implicit_concatenated: _, - unicode: _, - range: _, - }) => Self::StringLiteral(ExprStringLiteral { value }), - ast::Expr::BytesLiteral(ast::ExprBytesLiteral { - value, - // Compare bytes based on resolved value, not representation (i.e., ignore whether - // the bytes was implicitly concatenated). - implicit_concatenated: _, - range: _, - }) => Self::BytesLiteral(ExprBytesLiteral { value }), + ast::Expr::FString(ast::ExprFString { value, range: _ }) => { + Self::FString(ExprFString { + parts: value.iter().map(Into::into).collect(), + }) + } + ast::Expr::StringLiteral(ast::ExprStringLiteral { value, range: _ }) => { + Self::StringLiteral(ExprStringLiteral { + parts: value.iter().map(Into::into).collect(), + }) + } + ast::Expr::BytesLiteral(ast::ExprBytesLiteral { value, range: _ }) => { + Self::BytesLiteral(ExprBytesLiteral { + parts: value.iter().map(Into::into).collect(), + }) + } ast::Expr::NumberLiteral(ast::ExprNumberLiteral { value, range: _ }) => { Self::NumberLiteral(ExprNumberLiteral { value: value.into(), @@ -964,7 +1034,7 @@ impl<'a> From<&'a ast::Expr> for ComparableExpr<'a> { Self::BoolLiteral(ExprBoolLiteral { value }) } ast::Expr::NoneLiteral(_) => Self::NoneLiteral, - ast::Expr::EllipsisLiteral(_) => Self::EllispsisLiteral, + ast::Expr::EllipsisLiteral(_) => Self::EllipsisLiteral, ast::Expr::Attribute(ast::ExprAttribute { value, attr, diff --git a/crates/ruff_python_ast/src/expression.rs b/crates/ruff_python_ast/src/expression.rs index 83bac7272442c..56fecca6fc300 100644 --- a/crates/ruff_python_ast/src/expression.rs +++ b/crates/ruff_python_ast/src/expression.rs @@ -23,7 +23,6 @@ pub enum ExpressionRef<'a> { YieldFrom(&'a ast::ExprYieldFrom), Compare(&'a ast::ExprCompare), Call(&'a ast::ExprCall), - FormattedValue(&'a ast::ExprFormattedValue), FString(&'a ast::ExprFString), StringLiteral(&'a ast::ExprStringLiteral), BytesLiteral(&'a ast::ExprBytesLiteral), @@ -67,7 +66,6 @@ impl<'a> From<&'a Expr> for ExpressionRef<'a> { Expr::YieldFrom(value) => ExpressionRef::YieldFrom(value), Expr::Compare(value) => ExpressionRef::Compare(value), Expr::Call(value) => ExpressionRef::Call(value), - Expr::FormattedValue(value) => ExpressionRef::FormattedValue(value), Expr::FString(value) => ExpressionRef::FString(value), Expr::StringLiteral(value) => ExpressionRef::StringLiteral(value), Expr::BytesLiteral(value) => ExpressionRef::BytesLiteral(value), @@ -172,11 +170,6 @@ impl<'a> From<&'a ast::ExprCall> for ExpressionRef<'a> { Self::Call(value) } } -impl<'a> From<&'a ast::ExprFormattedValue> for ExpressionRef<'a> { - fn from(value: &'a ast::ExprFormattedValue) -> Self { - Self::FormattedValue(value) - } -} impl<'a> From<&'a ast::ExprFString> for ExpressionRef<'a> { fn from(value: &'a ast::ExprFString) -> Self { Self::FString(value) @@ -273,7 +266,6 @@ impl<'a> From> for AnyNodeRef<'a> { ExpressionRef::YieldFrom(expression) => AnyNodeRef::ExprYieldFrom(expression), ExpressionRef::Compare(expression) => AnyNodeRef::ExprCompare(expression), ExpressionRef::Call(expression) => AnyNodeRef::ExprCall(expression), - ExpressionRef::FormattedValue(expression) => AnyNodeRef::ExprFormattedValue(expression), ExpressionRef::FString(expression) => AnyNodeRef::ExprFString(expression), ExpressionRef::StringLiteral(expression) => AnyNodeRef::ExprStringLiteral(expression), ExpressionRef::BytesLiteral(expression) => AnyNodeRef::ExprBytesLiteral(expression), @@ -317,7 +309,6 @@ impl Ranged for ExpressionRef<'_> { ExpressionRef::YieldFrom(expression) => expression.range(), ExpressionRef::Compare(expression) => expression.range(), ExpressionRef::Call(expression) => expression.range(), - ExpressionRef::FormattedValue(expression) => expression.range(), ExpressionRef::FString(expression) => expression.range(), ExpressionRef::StringLiteral(expression) => expression.range(), ExpressionRef::BytesLiteral(expression) => expression.range(), @@ -361,3 +352,82 @@ impl Ranged for LiteralExpressionRef<'_> { } } } + +impl<'a> From> for AnyNodeRef<'a> { + fn from(value: LiteralExpressionRef<'a>) -> Self { + match value { + LiteralExpressionRef::StringLiteral(expression) => { + AnyNodeRef::ExprStringLiteral(expression) + } + LiteralExpressionRef::BytesLiteral(expression) => { + AnyNodeRef::ExprBytesLiteral(expression) + } + LiteralExpressionRef::NumberLiteral(expression) => { + AnyNodeRef::ExprNumberLiteral(expression) + } + LiteralExpressionRef::BooleanLiteral(expression) => { + AnyNodeRef::ExprBooleanLiteral(expression) + } + LiteralExpressionRef::NoneLiteral(expression) => { + AnyNodeRef::ExprNoneLiteral(expression) + } + LiteralExpressionRef::EllipsisLiteral(expression) => { + AnyNodeRef::ExprEllipsisLiteral(expression) + } + } + } +} + +impl LiteralExpressionRef<'_> { + /// Returns `true` if the literal is either a string or bytes literal that + /// is implicitly concatenated. + pub fn is_implicit_concatenated(&self) -> bool { + match self { + LiteralExpressionRef::StringLiteral(expression) => { + expression.value.is_implicit_concatenated() + } + LiteralExpressionRef::BytesLiteral(expression) => { + expression.value.is_implicit_concatenated() + } + _ => false, + } + } +} + +/// An enum that holds a reference to a string-like literal from the AST. +/// This includes string literals, bytes literals, and the literal parts of +/// f-strings. +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum StringLike<'a> { + StringLiteral(&'a ast::ExprStringLiteral), + BytesLiteral(&'a ast::ExprBytesLiteral), + FStringLiteral(&'a ast::FStringLiteralElement), +} + +impl<'a> From<&'a ast::ExprStringLiteral> for StringLike<'a> { + fn from(value: &'a ast::ExprStringLiteral) -> Self { + StringLike::StringLiteral(value) + } +} + +impl<'a> From<&'a ast::ExprBytesLiteral> for StringLike<'a> { + fn from(value: &'a ast::ExprBytesLiteral) -> Self { + StringLike::BytesLiteral(value) + } +} + +impl<'a> From<&'a ast::FStringLiteralElement> for StringLike<'a> { + fn from(value: &'a ast::FStringLiteralElement) -> Self { + StringLike::FStringLiteral(value) + } +} + +impl Ranged for StringLike<'_> { + fn range(&self) -> TextRange { + match self { + StringLike::StringLiteral(literal) => literal.range(), + StringLike::BytesLiteral(literal) => literal.range(), + StringLike::FStringLiteral(literal) => literal.range(), + } + } +} diff --git a/crates/ruff_python_ast/src/helpers.rs b/crates/ruff_python_ast/src/helpers.rs index 24b63669c1e21..fceba83d02a80 100644 --- a/crates/ruff_python_ast/src/helpers.rs +++ b/crates/ruff_python_ast/src/helpers.rs @@ -12,8 +12,8 @@ use crate::parenthesize::parenthesized_range; use crate::statement_visitor::StatementVisitor; use crate::visitor::Visitor; use crate::{ - self as ast, Arguments, CmpOp, ExceptHandler, Expr, MatchCase, Operator, Pattern, Stmt, - TypeParam, + self as ast, Arguments, CmpOp, ExceptHandler, Expr, FStringElement, MatchCase, Operator, + Pattern, Stmt, TypeParam, }; use crate::{AnyNodeRef, ExprContext}; @@ -133,10 +133,12 @@ pub fn any_over_expr(expr: &Expr, func: &dyn Fn(&Expr) -> bool) -> bool { return true; } match expr { - Expr::BoolOp(ast::ExprBoolOp { values, .. }) - | Expr::FString(ast::ExprFString { values, .. }) => { + Expr::BoolOp(ast::ExprBoolOp { values, .. }) => { values.iter().any(|expr| any_over_expr(expr, func)) } + Expr::FString(ast::ExprFString { value, .. }) => value + .elements() + .any(|expr| any_over_f_string_element(expr, func)), Expr::NamedExpr(ast::ExprNamedExpr { target, value, @@ -229,14 +231,6 @@ pub fn any_over_expr(expr: &Expr, func: &dyn Fn(&Expr) -> bool) -> bool { .iter() .any(|keyword| any_over_expr(&keyword.value, func)) } - Expr::FormattedValue(ast::ExprFormattedValue { - value, format_spec, .. - }) => { - any_over_expr(value, func) - || format_spec - .as_ref() - .is_some_and(|value| any_over_expr(value, func)) - } Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => { any_over_expr(value, func) || any_over_expr(slice, func) } @@ -313,6 +307,24 @@ pub fn any_over_pattern(pattern: &Pattern, func: &dyn Fn(&Expr) -> bool) -> bool } } +pub fn any_over_f_string_element(element: &FStringElement, func: &dyn Fn(&Expr) -> bool) -> bool { + match element { + FStringElement::Literal(_) => false, + FStringElement::Expression(ast::FStringExpressionElement { + expression, + format_spec, + .. + }) => { + any_over_expr(expression, func) + || format_spec.as_ref().is_some_and(|spec| { + spec.elements + .iter() + .any(|spec_element| any_over_f_string_element(spec_element, func)) + }) + } + } +} + pub fn any_over_stmt(stmt: &Stmt, func: &dyn Fn(&Expr) -> bool) -> bool { match stmt { Stmt::FunctionDef(ast::StmtFunctionDef { @@ -909,6 +921,180 @@ where } } +/// Returns `true` if the function has an implicit return. +pub fn implicit_return(function: &ast::StmtFunctionDef) -> bool { + /// Returns `true` if the body may break via a `break` statement. + fn sometimes_breaks(stmts: &[Stmt]) -> bool { + for stmt in stmts { + match stmt { + Stmt::For(ast::StmtFor { body, orelse, .. }) => { + if returns(body) { + return false; + } + if sometimes_breaks(orelse) { + return true; + } + } + Stmt::While(ast::StmtWhile { body, orelse, .. }) => { + if returns(body) { + return false; + } + if sometimes_breaks(orelse) { + return true; + } + } + Stmt::If(ast::StmtIf { + body, + elif_else_clauses, + .. + }) => { + if std::iter::once(body) + .chain(elif_else_clauses.iter().map(|clause| &clause.body)) + .any(|body| sometimes_breaks(body)) + { + return true; + } + } + Stmt::Match(ast::StmtMatch { cases, .. }) => { + if cases.iter().any(|case| sometimes_breaks(&case.body)) { + return true; + } + } + Stmt::Try(ast::StmtTry { + body, + handlers, + orelse, + finalbody, + .. + }) => { + if sometimes_breaks(body) + || handlers.iter().any(|handler| { + let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { + body, + .. + }) = handler; + sometimes_breaks(body) + }) + || sometimes_breaks(orelse) + || sometimes_breaks(finalbody) + { + return true; + } + } + Stmt::With(ast::StmtWith { body, .. }) => { + if sometimes_breaks(body) { + return true; + } + } + Stmt::Break(_) => return true, + Stmt::Return(_) => return false, + Stmt::Raise(_) => return false, + _ => {} + } + } + false + } + + /// Returns `true` if the body may break via a `break` statement. + fn always_breaks(stmts: &[Stmt]) -> bool { + for stmt in stmts { + match stmt { + Stmt::Break(_) => return true, + Stmt::Return(_) => return false, + Stmt::Raise(_) => return false, + _ => {} + } + } + false + } + + /// Returns `true` if the body contains a branch that ends without an explicit `return` or + /// `raise` statement. + fn returns(stmts: &[Stmt]) -> bool { + for stmt in stmts.iter().rev() { + match stmt { + Stmt::For(ast::StmtFor { body, orelse, .. }) => { + if always_breaks(body) { + return false; + } + if returns(body) { + return true; + } + if returns(orelse) && !sometimes_breaks(body) { + return true; + } + } + Stmt::While(ast::StmtWhile { body, orelse, .. }) => { + if always_breaks(body) { + return false; + } + if returns(body) { + return true; + } + if returns(orelse) && !sometimes_breaks(body) { + return true; + } + } + Stmt::If(ast::StmtIf { + body, + elif_else_clauses, + .. + }) => { + if elif_else_clauses.iter().any(|clause| clause.test.is_none()) + && std::iter::once(body) + .chain(elif_else_clauses.iter().map(|clause| &clause.body)) + .all(|body| returns(body)) + { + return true; + } + } + Stmt::Match(ast::StmtMatch { cases, .. }) => { + // Note: we assume the `match` is exhaustive. + if cases.iter().all(|case| returns(&case.body)) { + return true; + } + } + Stmt::Try(ast::StmtTry { + body, + handlers, + orelse, + finalbody, + .. + }) => { + // If the `finally` block returns, the `try` block must also return. + if returns(finalbody) { + return true; + } + + // If the `body` or the `else` block returns, the `try` block must also return. + if (returns(body) || returns(orelse)) + && handlers.iter().all(|handler| { + let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { + body, + .. + }) = handler; + returns(body) + }) + { + return true; + } + } + Stmt::With(ast::StmtWith { body, .. }) => { + if returns(body) { + return true; + } + } + Stmt::Return(_) => return true, + Stmt::Raise(_) => return true, + _ => {} + } + } + false + } + + !returns(&function.body) +} + /// A [`StatementVisitor`] that collects all `raise` statements in a function or method. #[derive(Default)] pub struct RaiseStatementVisitor<'a> { @@ -1139,16 +1325,21 @@ impl Truthiness { } Expr::NoneLiteral(_) => Self::Falsey, Expr::EllipsisLiteral(_) => Self::Truthy, - Expr::FString(ast::ExprFString { values, .. }) => { - if values.is_empty() { - Self::Falsey - } else if values.iter().any(|value| { - if let Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) = &value { - !value.is_empty() - } else { - false - } + Expr::FString(ast::ExprFString { value, .. }) => { + if value.iter().all(|part| match part { + ast::FStringPart::Literal(string_literal) => string_literal.is_empty(), + ast::FStringPart::FString(f_string) => f_string.elements.is_empty(), }) { + Self::Falsey + } else if value + .elements() + .any(|f_string_element| match f_string_element { + ast::FStringElement::Literal(ast::FStringLiteralElement { + value, .. + }) => !value.is_empty(), + ast::FStringElement::Expression(_) => true, + }) + { Self::Truthy } else { Self::Unknown @@ -1288,6 +1479,50 @@ pub fn pep_604_union(elts: &[Expr]) -> Expr { } } +pub fn typing_optional(elt: Expr, binding: String) -> Expr { + Expr::Subscript(ast::ExprSubscript { + value: Box::new(Expr::Name(ast::ExprName { + id: binding, + range: TextRange::default(), + ctx: ExprContext::Load, + })), + slice: Box::new(elt), + ctx: ExprContext::Load, + range: TextRange::default(), + }) +} + +pub fn typing_union(elts: &[Expr], binding: String) -> Expr { + fn tuple(elts: &[Expr]) -> Expr { + match elts { + [] => Expr::Tuple(ast::ExprTuple { + elts: vec![], + ctx: ExprContext::Load, + range: TextRange::default(), + }), + [Expr::Tuple(ast::ExprTuple { elts, .. })] => pep_604_union(elts), + [elt] => elt.clone(), + [rest @ .., elt] => Expr::BinOp(ast::ExprBinOp { + left: Box::new(tuple(rest)), + op: Operator::BitOr, + right: Box::new(elt.clone()), + range: TextRange::default(), + }), + } + } + + Expr::Subscript(ast::ExprSubscript { + value: Box::new(Expr::Name(ast::ExprName { + id: binding, + range: TextRange::default(), + ctx: ExprContext::Load, + })), + slice: Box::new(tuple(elts)), + ctx: ExprContext::Load, + range: TextRange::default(), + }) +} + #[cfg(test)] mod tests { use std::borrow::Cow; diff --git a/crates/ruff_python_ast/src/lib.rs b/crates/ruff_python_ast/src/lib.rs index 210e287eed372..1fb53dc8c7bf6 100644 --- a/crates/ruff_python_ast/src/lib.rs +++ b/crates/ruff_python_ast/src/lib.rs @@ -68,7 +68,7 @@ pub enum TomlSourceType { Unrecognized, } -#[derive(Clone, Copy, Debug, Default, PartialEq, is_macro::Is)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, is_macro::Is)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum PySourceType { /// The source is a Python file (`.py`). diff --git a/crates/ruff_python_ast/src/node.rs b/crates/ruff_python_ast/src/node.rs index e1a3b5ebf6486..35a536004c2a3 100644 --- a/crates/ruff_python_ast/src/node.rs +++ b/crates/ruff_python_ast/src/node.rs @@ -1,7 +1,7 @@ use crate::visitor::preorder::PreorderVisitor; use crate::{ self as ast, Alias, ArgOrKeyword, Arguments, Comprehension, Decorator, ExceptHandler, Expr, - Keyword, MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, + FStringElement, Keyword, MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, PatternArguments, PatternKeyword, Stmt, TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, WithItem, }; @@ -71,7 +71,6 @@ pub enum AnyNode { ExprYieldFrom(ast::ExprYieldFrom), ExprCompare(ast::ExprCompare), ExprCall(ast::ExprCall), - ExprFormattedValue(ast::ExprFormattedValue), ExprFString(ast::ExprFString), ExprStringLiteral(ast::ExprStringLiteral), ExprBytesLiteral(ast::ExprBytesLiteral), @@ -88,6 +87,8 @@ pub enum AnyNode { ExprSlice(ast::ExprSlice), ExprIpyEscapeCommand(ast::ExprIpyEscapeCommand), ExceptHandlerExceptHandler(ast::ExceptHandlerExceptHandler), + FStringExpressionElement(ast::FStringExpressionElement), + FStringLiteralElement(ast::FStringLiteralElement), PatternMatchValue(ast::PatternMatchValue), PatternMatchSingleton(ast::PatternMatchSingleton), PatternMatchSequence(ast::PatternMatchSequence), @@ -113,6 +114,9 @@ pub enum AnyNode { TypeParamTypeVar(TypeParamTypeVar), TypeParamTypeVarTuple(TypeParamTypeVarTuple), TypeParamParamSpec(TypeParamParamSpec), + FString(ast::FString), + StringLiteral(ast::StringLiteral), + BytesLiteral(ast::BytesLiteral), } impl AnyNode { @@ -163,7 +167,8 @@ impl AnyNode { | AnyNode::ExprYieldFrom(_) | AnyNode::ExprCompare(_) | AnyNode::ExprCall(_) - | AnyNode::ExprFormattedValue(_) + | AnyNode::FStringExpressionElement(_) + | AnyNode::FStringLiteralElement(_) | AnyNode::ExprFString(_) | AnyNode::ExprStringLiteral(_) | AnyNode::ExprBytesLiteral(_) @@ -204,6 +209,9 @@ impl AnyNode { | AnyNode::TypeParamTypeVar(_) | AnyNode::TypeParamTypeVarTuple(_) | AnyNode::TypeParamParamSpec(_) + | AnyNode::FString(_) + | AnyNode::StringLiteral(_) + | AnyNode::BytesLiteral(_) | AnyNode::ElifElseClause(_) => None, } } @@ -227,7 +235,6 @@ impl AnyNode { AnyNode::ExprYieldFrom(node) => Some(Expr::YieldFrom(node)), AnyNode::ExprCompare(node) => Some(Expr::Compare(node)), AnyNode::ExprCall(node) => Some(Expr::Call(node)), - AnyNode::ExprFormattedValue(node) => Some(Expr::FormattedValue(node)), AnyNode::ExprFString(node) => Some(Expr::FString(node)), AnyNode::ExprStringLiteral(node) => Some(Expr::StringLiteral(node)), AnyNode::ExprBytesLiteral(node) => Some(Expr::BytesLiteral(node)), @@ -272,6 +279,8 @@ impl AnyNode { | AnyNode::StmtContinue(_) | AnyNode::StmtIpyEscapeCommand(_) | AnyNode::ExceptHandlerExceptHandler(_) + | AnyNode::FStringExpressionElement(_) + | AnyNode::FStringLiteralElement(_) | AnyNode::PatternMatchValue(_) | AnyNode::PatternMatchSingleton(_) | AnyNode::PatternMatchSequence(_) @@ -296,6 +305,9 @@ impl AnyNode { | AnyNode::TypeParamTypeVar(_) | AnyNode::TypeParamTypeVarTuple(_) | AnyNode::TypeParamParamSpec(_) + | AnyNode::FString(_) + | AnyNode::StringLiteral(_) + | AnyNode::BytesLiteral(_) | AnyNode::ElifElseClause(_) => None, } } @@ -347,7 +359,8 @@ impl AnyNode { | AnyNode::ExprYieldFrom(_) | AnyNode::ExprCompare(_) | AnyNode::ExprCall(_) - | AnyNode::ExprFormattedValue(_) + | AnyNode::FStringExpressionElement(_) + | AnyNode::FStringLiteralElement(_) | AnyNode::ExprFString(_) | AnyNode::ExprStringLiteral(_) | AnyNode::ExprBytesLiteral(_) @@ -388,6 +401,9 @@ impl AnyNode { | AnyNode::TypeParamTypeVar(_) | AnyNode::TypeParamTypeVarTuple(_) | AnyNode::TypeParamParamSpec(_) + | AnyNode::FString(_) + | AnyNode::StringLiteral(_) + | AnyNode::BytesLiteral(_) | AnyNode::ElifElseClause(_) => None, } } @@ -447,7 +463,8 @@ impl AnyNode { | AnyNode::ExprYieldFrom(_) | AnyNode::ExprCompare(_) | AnyNode::ExprCall(_) - | AnyNode::ExprFormattedValue(_) + | AnyNode::FStringExpressionElement(_) + | AnyNode::FStringLiteralElement(_) | AnyNode::ExprFString(_) | AnyNode::ExprStringLiteral(_) | AnyNode::ExprBytesLiteral(_) @@ -480,6 +497,9 @@ impl AnyNode { | AnyNode::TypeParamTypeVar(_) | AnyNode::TypeParamTypeVarTuple(_) | AnyNode::TypeParamParamSpec(_) + | AnyNode::FString(_) + | AnyNode::StringLiteral(_) + | AnyNode::BytesLiteral(_) | AnyNode::ElifElseClause(_) => None, } } @@ -532,7 +552,8 @@ impl AnyNode { | AnyNode::ExprYieldFrom(_) | AnyNode::ExprCompare(_) | AnyNode::ExprCall(_) - | AnyNode::ExprFormattedValue(_) + | AnyNode::FStringExpressionElement(_) + | AnyNode::FStringLiteralElement(_) | AnyNode::ExprFString(_) | AnyNode::ExprStringLiteral(_) | AnyNode::ExprBytesLiteral(_) @@ -572,6 +593,9 @@ impl AnyNode { | AnyNode::TypeParamTypeVar(_) | AnyNode::TypeParamTypeVarTuple(_) | AnyNode::TypeParamParamSpec(_) + | AnyNode::FString(_) + | AnyNode::StringLiteral(_) + | AnyNode::BytesLiteral(_) | AnyNode::ElifElseClause(_) => None, } } @@ -642,7 +666,8 @@ impl AnyNode { Self::ExprYieldFrom(node) => AnyNodeRef::ExprYieldFrom(node), Self::ExprCompare(node) => AnyNodeRef::ExprCompare(node), Self::ExprCall(node) => AnyNodeRef::ExprCall(node), - Self::ExprFormattedValue(node) => AnyNodeRef::ExprFormattedValue(node), + Self::FStringExpressionElement(node) => AnyNodeRef::FStringExpressionElement(node), + Self::FStringLiteralElement(node) => AnyNodeRef::FStringLiteralElement(node), Self::ExprFString(node) => AnyNodeRef::ExprFString(node), Self::ExprStringLiteral(node) => AnyNodeRef::ExprStringLiteral(node), Self::ExprBytesLiteral(node) => AnyNodeRef::ExprBytesLiteral(node), @@ -683,6 +708,9 @@ impl AnyNode { Self::TypeParamTypeVar(node) => AnyNodeRef::TypeParamTypeVar(node), Self::TypeParamTypeVarTuple(node) => AnyNodeRef::TypeParamTypeVarTuple(node), Self::TypeParamParamSpec(node) => AnyNodeRef::TypeParamParamSpec(node), + Self::FString(node) => AnyNodeRef::FString(node), + Self::StringLiteral(node) => AnyNodeRef::StringLiteral(node), + Self::BytesLiteral(node) => AnyNodeRef::BytesLiteral(node), Self::ElifElseClause(node) => AnyNodeRef::ElifElseClause(node), } } @@ -2600,12 +2628,12 @@ impl AstNode for ast::ExprCall { visitor.visit_arguments(arguments); } } -impl AstNode for ast::ExprFormattedValue { +impl AstNode for ast::FStringExpressionElement { fn cast(kind: AnyNode) -> Option where Self: Sized, { - if let AnyNode::ExprFormattedValue(node) = kind { + if let AnyNode::FStringExpressionElement(node) = kind { Some(node) } else { None @@ -2613,7 +2641,7 @@ impl AstNode for ast::ExprFormattedValue { } fn cast_ref(kind: AnyNodeRef) -> Option<&Self> { - if let AnyNodeRef::ExprFormattedValue(node) = kind { + if let AnyNodeRef::FStringExpressionElement(node) = kind { Some(node) } else { None @@ -2632,16 +2660,54 @@ impl AstNode for ast::ExprFormattedValue { where V: PreorderVisitor<'a> + ?Sized, { - let ast::ExprFormattedValue { - value, format_spec, .. + let ast::FStringExpressionElement { + expression, + format_spec, + .. } = self; - visitor.visit_expr(value); + visitor.visit_expr(expression); - if let Some(expr) = format_spec { - visitor.visit_format_spec(expr); + if let Some(format_spec) = format_spec { + for spec_part in &format_spec.elements { + visitor.visit_f_string_element(spec_part); + } } } } +impl AstNode for ast::FStringLiteralElement { + fn cast(kind: AnyNode) -> Option + where + Self: Sized, + { + if let AnyNode::FStringLiteralElement(node) = kind { + Some(node) + } else { + None + } + } + + fn cast_ref(kind: AnyNodeRef) -> Option<&Self> { + if let AnyNodeRef::FStringLiteralElement(node) = kind { + Some(node) + } else { + None + } + } + + fn as_any_node_ref(&self) -> AnyNodeRef { + AnyNodeRef::from(self) + } + + fn into_any_node(self) -> AnyNode { + AnyNode::from(self) + } + + fn visit_preorder<'a, V>(&'a self, _visitor: &mut V) + where + V: PreorderVisitor<'a> + ?Sized, + { + } +} impl AstNode for ast::ExprFString { fn cast(kind: AnyNode) -> Option where @@ -2674,14 +2740,17 @@ impl AstNode for ast::ExprFString { where V: PreorderVisitor<'a> + ?Sized, { - let ast::ExprFString { - values, - implicit_concatenated: _, - range: _, - } = self; + let ast::ExprFString { value, range: _ } = self; - for expr in values { - visitor.visit_expr(expr); + for f_string_part in value { + match f_string_part { + ast::FStringPart::Literal(string_literal) => { + visitor.visit_string_literal(string_literal); + } + ast::FStringPart::FString(f_string) => { + visitor.visit_f_string(f_string); + } + } } } } @@ -2713,10 +2782,15 @@ impl AstNode for ast::ExprStringLiteral { AnyNode::from(self) } - fn visit_preorder<'a, V>(&'a self, _visitor: &mut V) + fn visit_preorder<'a, V>(&'a self, visitor: &mut V) where V: PreorderVisitor<'a> + ?Sized, { + let ast::ExprStringLiteral { value, range: _ } = self; + + for string_literal in value { + visitor.visit_string_literal(string_literal); + } } } impl AstNode for ast::ExprBytesLiteral { @@ -2747,10 +2821,15 @@ impl AstNode for ast::ExprBytesLiteral { AnyNode::from(self) } - fn visit_preorder<'a, V>(&'a self, _visitor: &mut V) + fn visit_preorder<'a, V>(&'a self, visitor: &mut V) where V: PreorderVisitor<'a> + ?Sized, { + let ast::ExprBytesLiteral { value, range: _ } = self; + + for bytes_literal in value { + visitor.visit_bytes_literal(bytes_literal); + } } } impl AstNode for ast::ExprNumberLiteral { @@ -4273,6 +4352,114 @@ impl AstNode for ast::TypeParamParamSpec { let ast::TypeParamParamSpec { range: _, name: _ } = self; } } +impl AstNode for ast::FString { + fn cast(kind: AnyNode) -> Option + where + Self: Sized, + { + if let AnyNode::FString(node) = kind { + Some(node) + } else { + None + } + } + + fn cast_ref(kind: AnyNodeRef) -> Option<&Self> { + if let AnyNodeRef::FString(node) = kind { + Some(node) + } else { + None + } + } + + fn as_any_node_ref(&self) -> AnyNodeRef { + AnyNodeRef::from(self) + } + + fn into_any_node(self) -> AnyNode { + AnyNode::from(self) + } + + fn visit_preorder<'a, V>(&'a self, visitor: &mut V) + where + V: PreorderVisitor<'a> + ?Sized, + { + let ast::FString { elements, range: _ } = self; + + for fstring_element in elements { + visitor.visit_f_string_element(fstring_element); + } + } +} +impl AstNode for ast::StringLiteral { + fn cast(kind: AnyNode) -> Option + where + Self: Sized, + { + if let AnyNode::StringLiteral(node) = kind { + Some(node) + } else { + None + } + } + + fn cast_ref(kind: AnyNodeRef) -> Option<&Self> { + if let AnyNodeRef::StringLiteral(node) = kind { + Some(node) + } else { + None + } + } + + fn as_any_node_ref(&self) -> AnyNodeRef { + AnyNodeRef::from(self) + } + + fn into_any_node(self) -> AnyNode { + AnyNode::from(self) + } + + fn visit_preorder<'a, V>(&'a self, _visitor: &mut V) + where + V: PreorderVisitor<'a> + ?Sized, + { + } +} +impl AstNode for ast::BytesLiteral { + fn cast(kind: AnyNode) -> Option + where + Self: Sized, + { + if let AnyNode::BytesLiteral(node) = kind { + Some(node) + } else { + None + } + } + + fn cast_ref(kind: AnyNodeRef) -> Option<&Self> { + if let AnyNodeRef::BytesLiteral(node) = kind { + Some(node) + } else { + None + } + } + + fn as_any_node_ref(&self) -> AnyNodeRef { + AnyNodeRef::from(self) + } + + fn into_any_node(self) -> AnyNode { + AnyNode::from(self) + } + + fn visit_preorder<'a, V>(&'a self, _visitor: &mut V) + where + V: PreorderVisitor<'a> + ?Sized, + { + } +} + impl From for AnyNode { fn from(stmt: Stmt) -> Self { match stmt { @@ -4325,7 +4512,6 @@ impl From for AnyNode { Expr::YieldFrom(node) => AnyNode::ExprYieldFrom(node), Expr::Compare(node) => AnyNode::ExprCompare(node), Expr::Call(node) => AnyNode::ExprCall(node), - Expr::FormattedValue(node) => AnyNode::ExprFormattedValue(node), Expr::FString(node) => AnyNode::ExprFString(node), Expr::StringLiteral(node) => AnyNode::ExprStringLiteral(node), Expr::BytesLiteral(node) => AnyNode::ExprBytesLiteral(node), @@ -4354,6 +4540,15 @@ impl From for AnyNode { } } +impl From for AnyNode { + fn from(element: FStringElement) -> Self { + match element { + FStringElement::Literal(node) => AnyNode::FStringLiteralElement(node), + FStringElement::Expression(node) => AnyNode::FStringExpressionElement(node), + } + } +} + impl From for AnyNode { fn from(pattern: Pattern) -> Self { match pattern { @@ -4647,9 +4842,15 @@ impl From for AnyNode { } } -impl From for AnyNode { - fn from(node: ast::ExprFormattedValue) -> Self { - AnyNode::ExprFormattedValue(node) +impl From for AnyNode { + fn from(node: ast::FStringExpressionElement) -> Self { + AnyNode::FStringExpressionElement(node) + } +} + +impl From for AnyNode { + fn from(node: ast::FStringLiteralElement) -> Self { + AnyNode::FStringLiteralElement(node) } } @@ -4882,6 +5083,24 @@ impl From for AnyNode { } } +impl From for AnyNode { + fn from(node: ast::FString) -> Self { + AnyNode::FString(node) + } +} + +impl From for AnyNode { + fn from(node: ast::StringLiteral) -> Self { + AnyNode::StringLiteral(node) + } +} + +impl From for AnyNode { + fn from(node: ast::BytesLiteral) -> Self { + AnyNode::BytesLiteral(node) + } +} + impl Ranged for AnyNode { fn range(&self) -> TextRange { match self { @@ -4929,7 +5148,8 @@ impl Ranged for AnyNode { AnyNode::ExprYieldFrom(node) => node.range(), AnyNode::ExprCompare(node) => node.range(), AnyNode::ExprCall(node) => node.range(), - AnyNode::ExprFormattedValue(node) => node.range(), + AnyNode::FStringExpressionElement(node) => node.range(), + AnyNode::FStringLiteralElement(node) => node.range(), AnyNode::ExprFString(node) => node.range(), AnyNode::ExprStringLiteral(node) => node.range(), AnyNode::ExprBytesLiteral(node) => node.range(), @@ -4970,6 +5190,9 @@ impl Ranged for AnyNode { AnyNode::TypeParamTypeVar(node) => node.range(), AnyNode::TypeParamTypeVarTuple(node) => node.range(), AnyNode::TypeParamParamSpec(node) => node.range(), + AnyNode::FString(node) => node.range(), + AnyNode::StringLiteral(node) => node.range(), + AnyNode::BytesLiteral(node) => node.range(), AnyNode::ElifElseClause(node) => node.range(), } } @@ -5021,7 +5244,8 @@ pub enum AnyNodeRef<'a> { ExprYieldFrom(&'a ast::ExprYieldFrom), ExprCompare(&'a ast::ExprCompare), ExprCall(&'a ast::ExprCall), - ExprFormattedValue(&'a ast::ExprFormattedValue), + FStringExpressionElement(&'a ast::FStringExpressionElement), + FStringLiteralElement(&'a ast::FStringLiteralElement), ExprFString(&'a ast::ExprFString), ExprStringLiteral(&'a ast::ExprStringLiteral), ExprBytesLiteral(&'a ast::ExprBytesLiteral), @@ -5062,6 +5286,9 @@ pub enum AnyNodeRef<'a> { TypeParamTypeVar(&'a TypeParamTypeVar), TypeParamTypeVarTuple(&'a TypeParamTypeVarTuple), TypeParamParamSpec(&'a TypeParamParamSpec), + FString(&'a ast::FString), + StringLiteral(&'a ast::StringLiteral), + BytesLiteral(&'a ast::BytesLiteral), ElifElseClause(&'a ast::ElifElseClause), } @@ -5112,7 +5339,8 @@ impl<'a> AnyNodeRef<'a> { AnyNodeRef::ExprYieldFrom(node) => NonNull::from(*node).cast(), AnyNodeRef::ExprCompare(node) => NonNull::from(*node).cast(), AnyNodeRef::ExprCall(node) => NonNull::from(*node).cast(), - AnyNodeRef::ExprFormattedValue(node) => NonNull::from(*node).cast(), + AnyNodeRef::FStringExpressionElement(node) => NonNull::from(*node).cast(), + AnyNodeRef::FStringLiteralElement(node) => NonNull::from(*node).cast(), AnyNodeRef::ExprFString(node) => NonNull::from(*node).cast(), AnyNodeRef::ExprStringLiteral(node) => NonNull::from(*node).cast(), AnyNodeRef::ExprBytesLiteral(node) => NonNull::from(*node).cast(), @@ -5153,6 +5381,9 @@ impl<'a> AnyNodeRef<'a> { AnyNodeRef::TypeParamTypeVar(node) => NonNull::from(*node).cast(), AnyNodeRef::TypeParamTypeVarTuple(node) => NonNull::from(*node).cast(), AnyNodeRef::TypeParamParamSpec(node) => NonNull::from(*node).cast(), + AnyNodeRef::FString(node) => NonNull::from(*node).cast(), + AnyNodeRef::StringLiteral(node) => NonNull::from(*node).cast(), + AnyNodeRef::BytesLiteral(node) => NonNull::from(*node).cast(), AnyNodeRef::ElifElseClause(node) => NonNull::from(*node).cast(), } } @@ -5209,7 +5440,8 @@ impl<'a> AnyNodeRef<'a> { AnyNodeRef::ExprYieldFrom(_) => NodeKind::ExprYieldFrom, AnyNodeRef::ExprCompare(_) => NodeKind::ExprCompare, AnyNodeRef::ExprCall(_) => NodeKind::ExprCall, - AnyNodeRef::ExprFormattedValue(_) => NodeKind::ExprFormattedValue, + AnyNodeRef::FStringExpressionElement(_) => NodeKind::FStringExpressionElement, + AnyNodeRef::FStringLiteralElement(_) => NodeKind::FStringLiteralElement, AnyNodeRef::ExprFString(_) => NodeKind::ExprFString, AnyNodeRef::ExprStringLiteral(_) => NodeKind::ExprStringLiteral, AnyNodeRef::ExprBytesLiteral(_) => NodeKind::ExprBytesLiteral, @@ -5250,6 +5482,9 @@ impl<'a> AnyNodeRef<'a> { AnyNodeRef::TypeParamTypeVar(_) => NodeKind::TypeParamTypeVar, AnyNodeRef::TypeParamTypeVarTuple(_) => NodeKind::TypeParamTypeVarTuple, AnyNodeRef::TypeParamParamSpec(_) => NodeKind::TypeParamParamSpec, + AnyNodeRef::FString(_) => NodeKind::FString, + AnyNodeRef::StringLiteral(_) => NodeKind::StringLiteral, + AnyNodeRef::BytesLiteral(_) => NodeKind::BytesLiteral, AnyNodeRef::ElifElseClause(_) => NodeKind::ElifElseClause, } } @@ -5301,7 +5536,8 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::ExprYieldFrom(_) | AnyNodeRef::ExprCompare(_) | AnyNodeRef::ExprCall(_) - | AnyNodeRef::ExprFormattedValue(_) + | AnyNodeRef::FStringExpressionElement(_) + | AnyNodeRef::FStringLiteralElement(_) | AnyNodeRef::ExprFString(_) | AnyNodeRef::ExprStringLiteral(_) | AnyNodeRef::ExprBytesLiteral(_) @@ -5342,6 +5578,9 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::TypeParamTypeVar(_) | AnyNodeRef::TypeParamTypeVarTuple(_) | AnyNodeRef::TypeParamParamSpec(_) + | AnyNodeRef::FString(_) + | AnyNodeRef::StringLiteral(_) + | AnyNodeRef::BytesLiteral(_) | AnyNodeRef::ElifElseClause(_) => false, } } @@ -5365,7 +5604,6 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::ExprYieldFrom(_) | AnyNodeRef::ExprCompare(_) | AnyNodeRef::ExprCall(_) - | AnyNodeRef::ExprFormattedValue(_) | AnyNodeRef::ExprFString(_) | AnyNodeRef::ExprStringLiteral(_) | AnyNodeRef::ExprBytesLiteral(_) @@ -5410,6 +5648,8 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::StmtContinue(_) | AnyNodeRef::StmtIpyEscapeCommand(_) | AnyNodeRef::ExceptHandlerExceptHandler(_) + | AnyNodeRef::FStringExpressionElement(_) + | AnyNodeRef::FStringLiteralElement(_) | AnyNodeRef::PatternMatchValue(_) | AnyNodeRef::PatternMatchSingleton(_) | AnyNodeRef::PatternMatchSequence(_) @@ -5434,6 +5674,9 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::TypeParamTypeVar(_) | AnyNodeRef::TypeParamTypeVarTuple(_) | AnyNodeRef::TypeParamParamSpec(_) + | AnyNodeRef::FString(_) + | AnyNodeRef::StringLiteral(_) + | AnyNodeRef::BytesLiteral(_) | AnyNodeRef::ElifElseClause(_) => false, } } @@ -5484,7 +5727,8 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::ExprYieldFrom(_) | AnyNodeRef::ExprCompare(_) | AnyNodeRef::ExprCall(_) - | AnyNodeRef::ExprFormattedValue(_) + | AnyNodeRef::FStringExpressionElement(_) + | AnyNodeRef::FStringLiteralElement(_) | AnyNodeRef::ExprFString(_) | AnyNodeRef::ExprStringLiteral(_) | AnyNodeRef::ExprBytesLiteral(_) @@ -5525,6 +5769,9 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::TypeParamTypeVar(_) | AnyNodeRef::TypeParamTypeVarTuple(_) | AnyNodeRef::TypeParamParamSpec(_) + | AnyNodeRef::FString(_) + | AnyNodeRef::StringLiteral(_) + | AnyNodeRef::BytesLiteral(_) | AnyNodeRef::ElifElseClause(_) => false, } } @@ -5584,7 +5831,8 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::ExprYieldFrom(_) | AnyNodeRef::ExprCompare(_) | AnyNodeRef::ExprCall(_) - | AnyNodeRef::ExprFormattedValue(_) + | AnyNodeRef::FStringExpressionElement(_) + | AnyNodeRef::FStringLiteralElement(_) | AnyNodeRef::ExprFString(_) | AnyNodeRef::ExprStringLiteral(_) | AnyNodeRef::ExprBytesLiteral(_) @@ -5617,6 +5865,9 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::TypeParamTypeVar(_) | AnyNodeRef::TypeParamTypeVarTuple(_) | AnyNodeRef::TypeParamParamSpec(_) + | AnyNodeRef::FString(_) + | AnyNodeRef::StringLiteral(_) + | AnyNodeRef::BytesLiteral(_) | AnyNodeRef::ElifElseClause(_) => false, } } @@ -5669,7 +5920,8 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::ExprYieldFrom(_) | AnyNodeRef::ExprCompare(_) | AnyNodeRef::ExprCall(_) - | AnyNodeRef::ExprFormattedValue(_) + | AnyNodeRef::FStringExpressionElement(_) + | AnyNodeRef::FStringLiteralElement(_) | AnyNodeRef::ExprFString(_) | AnyNodeRef::ExprStringLiteral(_) | AnyNodeRef::ExprBytesLiteral(_) @@ -5709,6 +5961,9 @@ impl<'a> AnyNodeRef<'a> { | AnyNodeRef::TypeParamTypeVar(_) | AnyNodeRef::TypeParamTypeVarTuple(_) | AnyNodeRef::TypeParamParamSpec(_) + | AnyNodeRef::FString(_) + | AnyNodeRef::StringLiteral(_) + | AnyNodeRef::BytesLiteral(_) | AnyNodeRef::ElifElseClause(_) => false, } } @@ -5788,7 +6043,8 @@ impl<'a> AnyNodeRef<'a> { AnyNodeRef::ExprYieldFrom(node) => node.visit_preorder(visitor), AnyNodeRef::ExprCompare(node) => node.visit_preorder(visitor), AnyNodeRef::ExprCall(node) => node.visit_preorder(visitor), - AnyNodeRef::ExprFormattedValue(node) => node.visit_preorder(visitor), + AnyNodeRef::FStringExpressionElement(node) => node.visit_preorder(visitor), + AnyNodeRef::FStringLiteralElement(node) => node.visit_preorder(visitor), AnyNodeRef::ExprFString(node) => node.visit_preorder(visitor), AnyNodeRef::ExprStringLiteral(node) => node.visit_preorder(visitor), AnyNodeRef::ExprBytesLiteral(node) => node.visit_preorder(visitor), @@ -5829,6 +6085,9 @@ impl<'a> AnyNodeRef<'a> { AnyNodeRef::TypeParamTypeVar(node) => node.visit_preorder(visitor), AnyNodeRef::TypeParamTypeVarTuple(node) => node.visit_preorder(visitor), AnyNodeRef::TypeParamParamSpec(node) => node.visit_preorder(visitor), + AnyNodeRef::FString(node) => node.visit_preorder(visitor), + AnyNodeRef::StringLiteral(node) => node.visit_preorder(visitor), + AnyNodeRef::BytesLiteral(node) => node.visit_preorder(visitor), AnyNodeRef::ElifElseClause(node) => node.visit_preorder(visitor), } } @@ -6164,9 +6423,15 @@ impl<'a> From<&'a ast::ExprCall> for AnyNodeRef<'a> { } } -impl<'a> From<&'a ast::ExprFormattedValue> for AnyNodeRef<'a> { - fn from(node: &'a ast::ExprFormattedValue) -> Self { - AnyNodeRef::ExprFormattedValue(node) +impl<'a> From<&'a ast::FStringExpressionElement> for AnyNodeRef<'a> { + fn from(node: &'a ast::FStringExpressionElement) -> Self { + AnyNodeRef::FStringExpressionElement(node) + } +} + +impl<'a> From<&'a ast::FStringLiteralElement> for AnyNodeRef<'a> { + fn from(node: &'a ast::FStringLiteralElement) -> Self { + AnyNodeRef::FStringLiteralElement(node) } } @@ -6355,6 +6620,24 @@ impl<'a> From<&'a TypeParamParamSpec> for AnyNodeRef<'a> { } } +impl<'a> From<&'a ast::FString> for AnyNodeRef<'a> { + fn from(node: &'a ast::FString) -> Self { + AnyNodeRef::FString(node) + } +} + +impl<'a> From<&'a ast::StringLiteral> for AnyNodeRef<'a> { + fn from(node: &'a ast::StringLiteral) -> Self { + AnyNodeRef::StringLiteral(node) + } +} + +impl<'a> From<&'a ast::BytesLiteral> for AnyNodeRef<'a> { + fn from(node: &'a ast::BytesLiteral) -> Self { + AnyNodeRef::BytesLiteral(node) + } +} + impl<'a> From<&'a Stmt> for AnyNodeRef<'a> { fn from(stmt: &'a Stmt) -> Self { match stmt { @@ -6407,7 +6690,6 @@ impl<'a> From<&'a Expr> for AnyNodeRef<'a> { Expr::YieldFrom(node) => AnyNodeRef::ExprYieldFrom(node), Expr::Compare(node) => AnyNodeRef::ExprCompare(node), Expr::Call(node) => AnyNodeRef::ExprCall(node), - Expr::FormattedValue(node) => AnyNodeRef::ExprFormattedValue(node), Expr::FString(node) => AnyNodeRef::ExprFString(node), Expr::StringLiteral(node) => AnyNodeRef::ExprStringLiteral(node), Expr::BytesLiteral(node) => AnyNodeRef::ExprBytesLiteral(node), @@ -6436,6 +6718,15 @@ impl<'a> From<&'a Mod> for AnyNodeRef<'a> { } } +impl<'a> From<&'a FStringElement> for AnyNodeRef<'a> { + fn from(element: &'a FStringElement) -> Self { + match element { + FStringElement::Expression(node) => AnyNodeRef::FStringExpressionElement(node), + FStringElement::Literal(node) => AnyNodeRef::FStringLiteralElement(node), + } + } +} + impl<'a> From<&'a Pattern> for AnyNodeRef<'a> { fn from(pattern: &'a Pattern) -> Self { match pattern { @@ -6564,7 +6855,8 @@ impl Ranged for AnyNodeRef<'_> { AnyNodeRef::ExprYieldFrom(node) => node.range(), AnyNodeRef::ExprCompare(node) => node.range(), AnyNodeRef::ExprCall(node) => node.range(), - AnyNodeRef::ExprFormattedValue(node) => node.range(), + AnyNodeRef::FStringExpressionElement(node) => node.range(), + AnyNodeRef::FStringLiteralElement(node) => node.range(), AnyNodeRef::ExprFString(node) => node.range(), AnyNodeRef::ExprStringLiteral(node) => node.range(), AnyNodeRef::ExprBytesLiteral(node) => node.range(), @@ -6606,6 +6898,9 @@ impl Ranged for AnyNodeRef<'_> { AnyNodeRef::TypeParamTypeVar(node) => node.range(), AnyNodeRef::TypeParamTypeVarTuple(node) => node.range(), AnyNodeRef::TypeParamParamSpec(node) => node.range(), + AnyNodeRef::FString(node) => node.range(), + AnyNodeRef::StringLiteral(node) => node.range(), + AnyNodeRef::BytesLiteral(node) => node.range(), } } } @@ -6658,7 +6953,8 @@ pub enum NodeKind { ExprYieldFrom, ExprCompare, ExprCall, - ExprFormattedValue, + FStringExpressionElement, + FStringLiteralElement, ExprFString, ExprStringLiteral, ExprBytesLiteral, @@ -6701,4 +6997,7 @@ pub enum NodeKind { TypeParamTypeVar, TypeParamTypeVarTuple, TypeParamParamSpec, + FString, + StringLiteral, + BytesLiteral, } diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 0af30770e4f32..f24a8063e008e 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1,14 +1,17 @@ #![allow(clippy::derive_partial_eq_without_eq)] -use itertools::Itertools; - +use std::cell::OnceCell; use std::fmt; use std::fmt::Debug; use std::ops::Deref; +use std::slice::{Iter, IterMut}; + +use itertools::Itertools; -use crate::{int, LiteralExpressionRef}; use ruff_text_size::{Ranged, TextRange, TextSize}; +use crate::{int, LiteralExpressionRef}; + /// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod) #[derive(Clone, Debug, PartialEq, is_macro::Is)] pub enum Mod { @@ -587,8 +590,6 @@ pub enum Expr { Compare(ExprCompare), #[is(name = "call_expr")] Call(ExprCall), - #[is(name = "formatted_value_expr")] - FormattedValue(ExprFormattedValue), #[is(name = "f_string_expr")] FString(ExprFString), #[is(name = "string_literal_expr")] @@ -640,6 +641,7 @@ impl Expr { ) } + /// Returns [`LiteralExpressionRef`] if the expression is a literal expression. pub fn as_literal_expr(&self) -> Option> { match self { Expr::StringLiteral(expr) => Some(LiteralExpressionRef::StringLiteral(expr)), @@ -651,24 +653,6 @@ impl Expr { _ => None, } } - - pub fn is_implicit_concatenated_string(&self) -> bool { - match self { - Expr::StringLiteral(ExprStringLiteral { - implicit_concatenated, - .. - }) - | Expr::BytesLiteral(ExprBytesLiteral { - implicit_concatenated, - .. - }) - | Expr::FString(ExprFString { - implicit_concatenated, - .. - }) => *implicit_concatenated, - _ => false, - } - } } /// An AST node used to represent a IPython escape command at the expression level. @@ -933,19 +917,51 @@ impl From for Expr { } } +#[derive(Clone, Debug, PartialEq)] +pub struct FStringFormatSpec { + pub range: TextRange, + pub elements: Vec, +} + +impl Ranged for FStringFormatSpec { + fn range(&self) -> TextRange { + self.range + } +} + /// See also [FormattedValue](https://docs.python.org/3/library/ast.html#ast.FormattedValue) #[derive(Clone, Debug, PartialEq)] -pub struct ExprFormattedValue { +pub struct FStringExpressionElement { pub range: TextRange, - pub value: Box, + pub expression: Box, pub debug_text: Option, pub conversion: ConversionFlag, - pub format_spec: Option>, + pub format_spec: Option>, } -impl From for Expr { - fn from(payload: ExprFormattedValue) -> Self { - Expr::FormattedValue(payload) +impl Ranged for FStringExpressionElement { + fn range(&self) -> TextRange { + self.range + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct FStringLiteralElement { + pub range: TextRange, + pub value: String, +} + +impl Ranged for FStringLiteralElement { + fn range(&self) -> TextRange { + self.range + } +} + +impl Deref for FStringLiteralElement { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.value.as_str() } } @@ -984,13 +1000,17 @@ pub struct DebugText { pub trailing: String, } -/// See also [JoinedStr](https://docs.python.org/3/library/ast.html#ast.JoinedStr) +/// An AST node used to represent an f-string. +/// +/// This type differs from the original Python AST ([JoinedStr]) in that it +/// doesn't join the implicitly concatenated parts into a single string. Instead, +/// it keeps them separate and provide various methods to access the parts. +/// +/// [JoinedStr]: https://docs.python.org/3/library/ast.html#ast.JoinedStr #[derive(Clone, Debug, PartialEq)] pub struct ExprFString { pub range: TextRange, - pub values: Vec, - /// Whether the f-string contains multiple string tokens that were implicitly concatenated. - pub implicit_concatenated: bool, + pub value: FStringValue, } impl From for Expr { @@ -999,12 +1019,189 @@ impl From for Expr { } } +/// The value representing an [`ExprFString`]. +#[derive(Clone, Debug, PartialEq)] +pub struct FStringValue { + inner: FStringValueInner, +} + +impl FStringValue { + /// Creates a new f-string with the given value. + pub fn single(value: FString) -> Self { + Self { + inner: FStringValueInner::Single(FStringPart::FString(value)), + } + } + + /// Creates a new f-string with the given values that represents an implicitly + /// concatenated f-string. + /// + /// # Panics + /// + /// Panics if `values` is less than 2. Use [`FStringValue::single`] instead. + pub fn concatenated(values: Vec) -> Self { + assert!(values.len() > 1); + Self { + inner: FStringValueInner::Concatenated(values), + } + } + + /// Returns `true` if the f-string is implicitly concatenated, `false` otherwise. + pub fn is_implicit_concatenated(&self) -> bool { + matches!(self.inner, FStringValueInner::Concatenated(_)) + } + + /// Returns a slice of all the [`FStringPart`]s contained in this value. + pub fn as_slice(&self) -> &[FStringPart] { + match &self.inner { + FStringValueInner::Single(part) => std::slice::from_ref(part), + FStringValueInner::Concatenated(parts) => parts, + } + } + + /// Returns a mutable slice of all the [`FStringPart`]s contained in this value. + fn as_mut_slice(&mut self) -> &mut [FStringPart] { + match &mut self.inner { + FStringValueInner::Single(part) => std::slice::from_mut(part), + FStringValueInner::Concatenated(parts) => parts, + } + } + + /// Returns an iterator over all the [`FStringPart`]s contained in this value. + pub fn iter(&self) -> Iter { + self.as_slice().iter() + } + + /// Returns an iterator over all the [`FStringPart`]s contained in this value + /// that allows modification. + pub(crate) fn iter_mut(&mut self) -> IterMut { + self.as_mut_slice().iter_mut() + } + + /// Returns an iterator over the [`StringLiteral`] parts contained in this value. + /// + /// Note that this doesn't nest into the f-string parts. For example, + /// + /// ```python + /// "foo" f"bar {x}" "baz" f"qux" + /// ``` + /// + /// Here, the string literal parts returned would be `"foo"` and `"baz"`. + pub fn literals(&self) -> impl Iterator { + self.iter().filter_map(|part| part.as_literal()) + } + + /// Returns an iterator over the [`FString`] parts contained in this value. + /// + /// Note that this doesn't nest into the f-string parts. For example, + /// + /// ```python + /// "foo" f"bar {x}" "baz" f"qux" + /// ``` + /// + /// Here, the f-string parts returned would be `f"bar {x}"` and `f"qux"`. + pub fn f_strings(&self) -> impl Iterator { + self.iter().filter_map(|part| part.as_f_string()) + } + + /// Returns an iterator over all the [`FStringElement`] contained in this value. + /// + /// An f-string element is what makes up an [`FString`] i.e., it is either a + /// string literal or an expression. In the following example, + /// + /// ```python + /// "foo" f"bar {x}" "baz" f"qux" + /// ``` + /// + /// The f-string elements returned would be string literal (`"bar "`), + /// expression (`x`) and string literal (`"qux"`). + pub fn elements(&self) -> impl Iterator { + self.f_strings().flat_map(|fstring| fstring.elements.iter()) + } +} + +impl<'a> IntoIterator for &'a FStringValue { + type Item = &'a FStringPart; + type IntoIter = Iter<'a, FStringPart>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +/// An internal representation of [`FStringValue`]. +#[derive(Clone, Debug, PartialEq)] +enum FStringValueInner { + /// A single f-string i.e., `f"foo"`. + /// + /// This is always going to be `FStringPart::FString` variant which is + /// maintained by the `FStringValue::single` constructor. + Single(FStringPart), + + /// An implicitly concatenated f-string i.e., `"foo" f"bar {x}"`. + Concatenated(Vec), +} + +/// An f-string part which is either a string literal or an f-string. +#[derive(Clone, Debug, PartialEq, is_macro::Is)] +pub enum FStringPart { + Literal(StringLiteral), + FString(FString), +} + +impl Ranged for FStringPart { + fn range(&self) -> TextRange { + match self { + FStringPart::Literal(string_literal) => string_literal.range(), + FStringPart::FString(f_string) => f_string.range(), + } + } +} + +/// An AST node that represents a single f-string which is part of an [`ExprFString`]. +#[derive(Clone, Debug, PartialEq)] +pub struct FString { + pub range: TextRange, + pub elements: Vec, +} + +impl Ranged for FString { + fn range(&self) -> TextRange { + self.range + } +} + +impl From for Expr { + fn from(payload: FString) -> Self { + ExprFString { + range: payload.range, + value: FStringValue::single(payload), + } + .into() + } +} + +#[derive(Clone, Debug, PartialEq, is_macro::Is)] +pub enum FStringElement { + Literal(FStringLiteralElement), + Expression(FStringExpressionElement), +} + +impl Ranged for FStringElement { + fn range(&self) -> TextRange { + match self { + FStringElement::Literal(node) => node.range(), + FStringElement::Expression(node) => node.range(), + } + } +} + +/// An AST node that represents either a single string literal or an implicitly +/// concatenated string literals. #[derive(Clone, Debug, Default, PartialEq)] pub struct ExprStringLiteral { pub range: TextRange, - pub value: String, - pub unicode: bool, - pub implicit_concatenated: bool, + pub value: StringLiteralValue, } impl From for Expr { @@ -1019,7 +1216,168 @@ impl Ranged for ExprStringLiteral { } } -impl Deref for ExprStringLiteral { +/// The value representing a [`ExprStringLiteral`]. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct StringLiteralValue { + inner: StringLiteralValueInner, +} + +impl StringLiteralValue { + /// Creates a new single string literal with the given value. + pub fn single(string: StringLiteral) -> Self { + Self { + inner: StringLiteralValueInner::Single(string), + } + } + + /// Creates a new string literal with the given values that represents an + /// implicitly concatenated strings. + /// + /// # Panics + /// + /// Panics if `strings` is less than 2. Use [`StringLiteralValue::single`] + /// instead. + pub fn concatenated(strings: Vec) -> Self { + assert!(strings.len() > 1); + Self { + inner: StringLiteralValueInner::Concatenated(ConcatenatedStringLiteral { + strings, + value: OnceCell::new(), + }), + } + } + + /// Returns `true` if the string literal is implicitly concatenated. + pub const fn is_implicit_concatenated(&self) -> bool { + matches!(self.inner, StringLiteralValueInner::Concatenated(_)) + } + + /// Returns `true` if the string literal is a unicode string. + /// + /// For an implicitly concatenated string, it returns `true` only if the first + /// string literal is a unicode string. + pub fn is_unicode(&self) -> bool { + self.iter().next().map_or(false, |part| part.unicode) + } + + /// Returns a slice of all the [`StringLiteral`] parts contained in this value. + pub fn as_slice(&self) -> &[StringLiteral] { + match &self.inner { + StringLiteralValueInner::Single(value) => std::slice::from_ref(value), + StringLiteralValueInner::Concatenated(value) => value.strings.as_slice(), + } + } + + /// Returns a mutable slice of all the [`StringLiteral`] parts contained in this value. + fn as_mut_slice(&mut self) -> &mut [StringLiteral] { + match &mut self.inner { + StringLiteralValueInner::Single(value) => std::slice::from_mut(value), + StringLiteralValueInner::Concatenated(value) => value.strings.as_mut_slice(), + } + } + + /// Returns an iterator over all the [`StringLiteral`] parts contained in this value. + pub fn iter(&self) -> Iter { + self.as_slice().iter() + } + + /// Returns an iterator over all the [`StringLiteral`] parts contained in this value + /// that allows modification. + pub(crate) fn iter_mut(&mut self) -> IterMut { + self.as_mut_slice().iter_mut() + } + + /// Returns `true` if the string literal value is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns the total length of the string literal value, in bytes, not + /// [`char`]s or graphemes. + pub fn len(&self) -> usize { + self.iter().fold(0, |acc, part| acc + part.value.len()) + } + + /// Returns an iterator over the [`char`]s of each string literal part. + pub fn chars(&self) -> impl Iterator + '_ { + self.iter().flat_map(|part| part.value.chars()) + } + + /// Returns the concatenated string value as a [`str`]. + /// + /// Note that this will perform an allocation on the first invocation if the + /// string value is implicitly concatenated. + pub fn to_str(&self) -> &str { + match &self.inner { + StringLiteralValueInner::Single(value) => value.as_str(), + StringLiteralValueInner::Concatenated(value) => value.to_str(), + } + } +} + +impl<'a> IntoIterator for &'a StringLiteralValue { + type Item = &'a StringLiteral; + type IntoIter = Iter<'a, StringLiteral>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl PartialEq for StringLiteralValue { + fn eq(&self, other: &str) -> bool { + if self.len() != other.len() { + return false; + } + // The `zip` here is safe because we have checked the length of both parts. + self.chars().zip(other.chars()).all(|(c1, c2)| c1 == c2) + } +} + +impl PartialEq for StringLiteralValue { + fn eq(&self, other: &String) -> bool { + self == other.as_str() + } +} + +impl fmt::Display for StringLiteralValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.to_str()) + } +} + +/// An internal representation of [`StringLiteralValue`]. +#[derive(Clone, Debug, PartialEq)] +enum StringLiteralValueInner { + /// A single string literal i.e., `"foo"`. + Single(StringLiteral), + + /// An implicitly concatenated string literals i.e., `"foo" "bar"`. + Concatenated(ConcatenatedStringLiteral), +} + +impl Default for StringLiteralValueInner { + fn default() -> Self { + Self::Single(StringLiteral::default()) + } +} + +/// An AST node that represents a single string literal which is part of an +/// [`ExprStringLiteral`]. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct StringLiteral { + pub range: TextRange, + pub value: String, + pub unicode: bool, +} + +impl Ranged for StringLiteral { + fn range(&self) -> TextRange { + self.range + } +} + +impl Deref for StringLiteral { type Target = str; fn deref(&self) -> &Self::Target { @@ -1027,11 +1385,69 @@ impl Deref for ExprStringLiteral { } } +impl StringLiteral { + /// Extracts a string slice containing the entire `String`. + pub fn as_str(&self) -> &str { + self + } +} + +impl From for Expr { + fn from(payload: StringLiteral) -> Self { + ExprStringLiteral { + range: payload.range, + value: StringLiteralValue::single(payload), + } + .into() + } +} + +/// An internal representation of [`StringLiteral`] that represents an +/// implicitly concatenated string. +#[derive(Clone)] +struct ConcatenatedStringLiteral { + /// Each string literal that makes up the concatenated string. + strings: Vec, + /// The concatenated string value. + value: OnceCell, +} + +impl ConcatenatedStringLiteral { + /// Extracts a string slice containing the entire concatenated string. + fn to_str(&self) -> &str { + self.value + .get_or_init(|| self.strings.iter().map(StringLiteral::as_str).collect()) + } +} + +impl PartialEq for ConcatenatedStringLiteral { + fn eq(&self, other: &Self) -> bool { + if self.strings.len() != other.strings.len() { + return false; + } + // The `zip` here is safe because we have checked the length of both parts. + self.strings + .iter() + .zip(other.strings.iter()) + .all(|(s1, s2)| s1 == s2) + } +} + +impl Debug for ConcatenatedStringLiteral { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ConcatenatedStringLiteral") + .field("strings", &self.strings) + .field("value", &self.to_str()) + .finish() + } +} + +/// An AST node that represents either a single bytes literal or an implicitly +/// concatenated bytes literals. #[derive(Clone, Debug, Default, PartialEq)] pub struct ExprBytesLiteral { pub range: TextRange, - pub value: Vec, - pub implicit_concatenated: bool, + pub value: BytesLiteralValue, } impl From for Expr { @@ -1046,6 +1462,158 @@ impl Ranged for ExprBytesLiteral { } } +/// The value representing a [`ExprBytesLiteral`]. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct BytesLiteralValue { + inner: BytesLiteralValueInner, +} + +impl BytesLiteralValue { + /// Creates a new single bytes literal with the given value. + pub fn single(value: BytesLiteral) -> Self { + Self { + inner: BytesLiteralValueInner::Single(value), + } + } + + /// Creates a new bytes literal with the given values that represents an + /// implicitly concatenated bytes. + /// + /// # Panics + /// + /// Panics if `values` is less than 2. Use [`BytesLiteralValue::single`] + /// instead. + pub fn concatenated(values: Vec) -> Self { + assert!(values.len() > 1); + Self { + inner: BytesLiteralValueInner::Concatenated(values), + } + } + + /// Returns `true` if the bytes literal is implicitly concatenated. + pub const fn is_implicit_concatenated(&self) -> bool { + matches!(self.inner, BytesLiteralValueInner::Concatenated(_)) + } + + /// Returns a slice of all the [`BytesLiteral`] parts contained in this value. + pub fn as_slice(&self) -> &[BytesLiteral] { + match &self.inner { + BytesLiteralValueInner::Single(value) => std::slice::from_ref(value), + BytesLiteralValueInner::Concatenated(value) => value.as_slice(), + } + } + + /// Returns a mutable slice of all the [`BytesLiteral`] parts contained in this value. + fn as_mut_slice(&mut self) -> &mut [BytesLiteral] { + match &mut self.inner { + BytesLiteralValueInner::Single(value) => std::slice::from_mut(value), + BytesLiteralValueInner::Concatenated(value) => value.as_mut_slice(), + } + } + + /// Returns an iterator over all the [`BytesLiteral`] parts contained in this value. + pub fn iter(&self) -> Iter { + self.as_slice().iter() + } + + /// Returns an iterator over all the [`BytesLiteral`] parts contained in this value + /// that allows modification. + pub(crate) fn iter_mut(&mut self) -> IterMut { + self.as_mut_slice().iter_mut() + } + + /// Returns `true` if the concatenated bytes has a length of zero. + pub fn is_empty(&self) -> bool { + self.iter().all(|part| part.is_empty()) + } + + /// Returns the length of the concatenated bytes. + pub fn len(&self) -> usize { + self.iter().map(|part| part.len()).sum() + } + + /// Returns an iterator over the bytes of the concatenated bytes. + fn bytes(&self) -> impl Iterator + '_ { + self.iter().flat_map(|part| part.as_slice().iter().copied()) + } +} + +impl<'a> IntoIterator for &'a BytesLiteralValue { + type Item = &'a BytesLiteral; + type IntoIter = Iter<'a, BytesLiteral>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl PartialEq<[u8]> for BytesLiteralValue { + fn eq(&self, other: &[u8]) -> bool { + if self.len() != other.len() { + return false; + } + // The `zip` here is safe because we have checked the length of both parts. + self.bytes() + .zip(other.iter().copied()) + .all(|(b1, b2)| b1 == b2) + } +} + +/// An internal representation of [`BytesLiteralValue`]. +#[derive(Clone, Debug, PartialEq)] +enum BytesLiteralValueInner { + /// A single bytes literal i.e., `b"foo"`. + Single(BytesLiteral), + + /// An implicitly concatenated bytes literals i.e., `b"foo" b"bar"`. + Concatenated(Vec), +} + +impl Default for BytesLiteralValueInner { + fn default() -> Self { + Self::Single(BytesLiteral::default()) + } +} + +/// An AST node that represents a single bytes literal which is part of an +/// [`ExprBytesLiteral`]. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct BytesLiteral { + pub range: TextRange, + pub value: Vec, +} + +impl Ranged for BytesLiteral { + fn range(&self) -> TextRange { + self.range + } +} + +impl Deref for BytesLiteral { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + self.value.as_slice() + } +} + +impl BytesLiteral { + /// Extracts a byte slice containing the entire [`BytesLiteral`]. + pub fn as_slice(&self) -> &[u8] { + self + } +} + +impl From for Expr { + fn from(payload: BytesLiteral) -> Self { + ExprBytesLiteral { + range: payload.range, + value: BytesLiteralValue::single(payload), + } + .into() + } +} + #[derive(Clone, Debug, PartialEq)] pub struct ExprNumberLiteral { pub range: TextRange, @@ -3016,11 +3584,6 @@ impl Ranged for crate::nodes::ExprCall { self.range } } -impl Ranged for crate::nodes::ExprFormattedValue { - fn range(&self) -> TextRange { - self.range - } -} impl Ranged for crate::nodes::ExprFString { fn range(&self) -> TextRange { self.range @@ -3086,14 +3649,13 @@ impl Ranged for crate::Expr { Self::YieldFrom(node) => node.range(), Self::Compare(node) => node.range(), Self::Call(node) => node.range(), - Self::FormattedValue(node) => node.range(), Self::FString(node) => node.range(), - Expr::StringLiteral(node) => node.range(), - Expr::BytesLiteral(node) => node.range(), - Expr::NumberLiteral(node) => node.range(), - Expr::BooleanLiteral(node) => node.range(), - Expr::NoneLiteral(node) => node.range(), - Expr::EllipsisLiteral(node) => node.range(), + Self::StringLiteral(node) => node.range(), + Self::BytesLiteral(node) => node.range(), + Self::NumberLiteral(node) => node.range(), + Self::BooleanLiteral(node) => node.range(), + Self::NoneLiteral(node) => node.range(), + Self::EllipsisLiteral(node) => node.range(), Self::Attribute(node) => node.range(), Self::Subscript(node) => node.range(), Self::Starred(node) => node.range(), @@ -3101,7 +3663,7 @@ impl Ranged for crate::Expr { Self::List(node) => node.range(), Self::Tuple(node) => node.range(), Self::Slice(node) => node.range(), - Expr::IpyEscapeCommand(node) => node.range(), + Self::IpyEscapeCommand(node) => node.range(), } } } @@ -3262,204 +3824,6 @@ impl Ranged for crate::nodes::ParameterWithDefault { } } -/// An expression that may be parenthesized. -#[derive(Clone, Debug)] -pub struct ParenthesizedExpr { - /// The range of the expression, including any parentheses. - pub range: TextRange, - /// The underlying expression. - pub expr: Expr, -} -impl ParenthesizedExpr { - /// Returns `true` if the expression is may be parenthesized. - pub fn is_parenthesized(&self) -> bool { - self.range != self.expr.range() - } -} -impl Ranged for ParenthesizedExpr { - fn range(&self) -> TextRange { - self.range - } -} -impl From for ParenthesizedExpr { - fn from(expr: Expr) -> Self { - ParenthesizedExpr { - range: expr.range(), - expr, - } - } -} -impl From for Expr { - fn from(parenthesized_expr: ParenthesizedExpr) -> Self { - parenthesized_expr.expr - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprIpyEscapeCommand) -> Self { - Expr::IpyEscapeCommand(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprBoolOp) -> Self { - Expr::BoolOp(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprNamedExpr) -> Self { - Expr::NamedExpr(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprBinOp) -> Self { - Expr::BinOp(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprUnaryOp) -> Self { - Expr::UnaryOp(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprLambda) -> Self { - Expr::Lambda(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprIfExp) -> Self { - Expr::IfExp(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprDict) -> Self { - Expr::Dict(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprSet) -> Self { - Expr::Set(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprListComp) -> Self { - Expr::ListComp(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprSetComp) -> Self { - Expr::SetComp(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprDictComp) -> Self { - Expr::DictComp(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprGeneratorExp) -> Self { - Expr::GeneratorExp(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprAwait) -> Self { - Expr::Await(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprYield) -> Self { - Expr::Yield(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprYieldFrom) -> Self { - Expr::YieldFrom(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprCompare) -> Self { - Expr::Compare(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprCall) -> Self { - Expr::Call(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprFormattedValue) -> Self { - Expr::FormattedValue(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprFString) -> Self { - Expr::FString(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprStringLiteral) -> Self { - Expr::StringLiteral(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprBytesLiteral) -> Self { - Expr::BytesLiteral(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprNumberLiteral) -> Self { - Expr::NumberLiteral(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprBooleanLiteral) -> Self { - Expr::BooleanLiteral(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprNoneLiteral) -> Self { - Expr::NoneLiteral(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprEllipsisLiteral) -> Self { - Expr::EllipsisLiteral(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprAttribute) -> Self { - Expr::Attribute(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprSubscript) -> Self { - Expr::Subscript(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprStarred) -> Self { - Expr::Starred(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprName) -> Self { - Expr::Name(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprList) -> Self { - Expr::List(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprTuple) -> Self { - Expr::Tuple(payload).into() - } -} -impl From for ParenthesizedExpr { - fn from(payload: ExprSlice) -> Self { - Expr::Slice(payload).into() - } -} - #[cfg(target_pointer_width = "64")] mod size_assertions { use static_assertions::assert_eq_size; diff --git a/crates/ruff_python_ast/src/relocate.rs b/crates/ruff_python_ast/src/relocate.rs index 19a126b3567ac..5c189fb4c6a73 100644 --- a/crates/ruff_python_ast/src/relocate.rs +++ b/crates/ruff_python_ast/src/relocate.rs @@ -68,9 +68,6 @@ impl Transformer for Relocator { Expr::Call(nodes::ExprCall { range, .. }) => { *range = self.range; } - Expr::FormattedValue(nodes::ExprFormattedValue { range, .. }) => { - *range = self.range; - } Expr::FString(nodes::ExprFString { range, .. }) => { *range = self.range; } diff --git a/crates/ruff_python_ast/src/visitor.rs b/crates/ruff_python_ast/src/visitor.rs index f740044fb5ffc..2d8773fcfdcb0 100644 --- a/crates/ruff_python_ast/src/visitor.rs +++ b/crates/ruff_python_ast/src/visitor.rs @@ -4,10 +4,10 @@ pub mod preorder; pub mod transformer; use crate::{ - self as ast, Alias, Arguments, BoolOp, CmpOp, Comprehension, Decorator, ElifElseClause, - ExceptHandler, Expr, ExprContext, Keyword, MatchCase, Operator, Parameter, Parameters, Pattern, - PatternArguments, PatternKeyword, Stmt, TypeParam, TypeParamTypeVar, TypeParams, UnaryOp, - WithItem, + self as ast, Alias, Arguments, BoolOp, BytesLiteral, CmpOp, Comprehension, Decorator, + ElifElseClause, ExceptHandler, Expr, ExprContext, FString, FStringElement, FStringPart, + Keyword, MatchCase, Operator, Parameter, Parameters, Pattern, PatternArguments, PatternKeyword, + Stmt, StringLiteral, TypeParam, TypeParamTypeVar, TypeParams, UnaryOp, WithItem, }; /// A trait for AST visitors. Visits all nodes in the AST recursively in evaluation-order. @@ -53,9 +53,6 @@ pub trait Visitor<'a> { fn visit_except_handler(&mut self, except_handler: &'a ExceptHandler) { walk_except_handler(self, except_handler); } - fn visit_format_spec(&mut self, format_spec: &'a Expr) { - walk_format_spec(self, format_spec); - } fn visit_arguments(&mut self, arguments: &'a Arguments) { walk_arguments(self, arguments); } @@ -98,6 +95,18 @@ pub trait Visitor<'a> { fn visit_elif_else_clause(&mut self, elif_else_clause: &'a ElifElseClause) { walk_elif_else_clause(self, elif_else_clause); } + fn visit_f_string(&mut self, f_string: &'a FString) { + walk_f_string(self, f_string); + } + fn visit_f_string_element(&mut self, f_string_element: &'a FStringElement) { + walk_f_string_element(self, f_string_element); + } + fn visit_string_literal(&mut self, string_literal: &'a StringLiteral) { + walk_string_literal(self, string_literal); + } + fn visit_bytes_literal(&mut self, bytes_literal: &'a BytesLiteral) { + walk_bytes_literal(self, bytes_literal); + } } pub fn walk_body<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, body: &'a [Stmt]) { @@ -467,22 +476,27 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) { visitor.visit_expr(func); visitor.visit_arguments(arguments); } - Expr::FormattedValue(ast::ExprFormattedValue { - value, format_spec, .. - }) => { - visitor.visit_expr(value); - if let Some(expr) = format_spec { - visitor.visit_format_spec(expr); + Expr::FString(ast::ExprFString { value, .. }) => { + for part in value { + match part { + FStringPart::Literal(string_literal) => { + visitor.visit_string_literal(string_literal); + } + FStringPart::FString(f_string) => visitor.visit_f_string(f_string), + } } } - Expr::FString(ast::ExprFString { values, .. }) => { - for expr in values { - visitor.visit_expr(expr); + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { + for string_literal in value { + visitor.visit_string_literal(string_literal); + } + } + Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => { + for bytes_literal in value { + visitor.visit_bytes_literal(bytes_literal); } } - Expr::StringLiteral(_) - | Expr::BytesLiteral(_) - | Expr::NumberLiteral(_) + Expr::NumberLiteral(_) | Expr::BooleanLiteral(_) | Expr::NoneLiteral(_) | Expr::EllipsisLiteral(_) => {} @@ -576,10 +590,6 @@ pub fn walk_except_handler<'a, V: Visitor<'a> + ?Sized>( } } -pub fn walk_format_spec<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, format_spec: &'a Expr) { - visitor.visit_expr(format_spec); -} - pub fn walk_arguments<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arguments: &'a Arguments) { // Note that the there might be keywords before the last arg, e.g. in // f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then @@ -729,20 +739,55 @@ pub fn walk_pattern_keyword<'a, V: Visitor<'a> + ?Sized>( visitor.visit_pattern(&pattern_keyword.pattern); } -#[allow(unused_variables)] -pub fn walk_expr_context<'a, V: Visitor<'a> + ?Sized>(visitor: &V, expr_context: &'a ExprContext) {} +pub fn walk_f_string<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, f_string: &'a FString) { + for f_string_element in &f_string.elements { + visitor.visit_f_string_element(f_string_element); + } +} + +pub fn walk_f_string_element<'a, V: Visitor<'a> + ?Sized>( + visitor: &mut V, + f_string_element: &'a FStringElement, +) { + if let ast::FStringElement::Expression(ast::FStringExpressionElement { + expression, + format_spec, + .. + }) = f_string_element + { + visitor.visit_expr(expression); + if let Some(format_spec) = format_spec { + for spec_element in &format_spec.elements { + visitor.visit_f_string_element(spec_element); + } + } + } +} + +pub fn walk_expr_context<'a, V: Visitor<'a> + ?Sized>( + _visitor: &V, + _expr_context: &'a ExprContext, +) { +} + +pub fn walk_bool_op<'a, V: Visitor<'a> + ?Sized>(_visitor: &V, _bool_op: &'a BoolOp) {} + +pub fn walk_operator<'a, V: Visitor<'a> + ?Sized>(_visitor: &V, _operator: &'a Operator) {} -#[allow(unused_variables)] -pub fn walk_bool_op<'a, V: Visitor<'a> + ?Sized>(visitor: &V, bool_op: &'a BoolOp) {} +pub fn walk_unary_op<'a, V: Visitor<'a> + ?Sized>(_visitor: &V, _unary_op: &'a UnaryOp) {} -#[allow(unused_variables)] -pub fn walk_operator<'a, V: Visitor<'a> + ?Sized>(visitor: &V, operator: &'a Operator) {} +pub fn walk_cmp_op<'a, V: Visitor<'a> + ?Sized>(_visitor: &V, _cmp_op: &'a CmpOp) {} -#[allow(unused_variables)] -pub fn walk_unary_op<'a, V: Visitor<'a> + ?Sized>(visitor: &V, unary_op: &'a UnaryOp) {} +pub fn walk_alias<'a, V: Visitor<'a> + ?Sized>(_visitor: &V, _alias: &'a Alias) {} -#[allow(unused_variables)] -pub fn walk_cmp_op<'a, V: Visitor<'a> + ?Sized>(visitor: &V, cmp_op: &'a CmpOp) {} +pub fn walk_string_literal<'a, V: Visitor<'a> + ?Sized>( + _visitor: &V, + _string_literal: &'a StringLiteral, +) { +} -#[allow(unused_variables)] -pub fn walk_alias<'a, V: Visitor<'a> + ?Sized>(visitor: &V, alias: &'a Alias) {} +pub fn walk_bytes_literal<'a, V: Visitor<'a> + ?Sized>( + _visitor: &V, + _bytes_literal: &'a BytesLiteral, +) { +} diff --git a/crates/ruff_python_ast/src/visitor/preorder.rs b/crates/ruff_python_ast/src/visitor/preorder.rs index 8de18d1413ff6..d560cb5fb0973 100644 --- a/crates/ruff_python_ast/src/visitor/preorder.rs +++ b/crates/ruff_python_ast/src/visitor/preorder.rs @@ -1,7 +1,8 @@ use crate::{ - Alias, Arguments, BoolOp, CmpOp, Comprehension, Decorator, ElifElseClause, ExceptHandler, Expr, - Keyword, MatchCase, Mod, Operator, Parameter, ParameterWithDefault, Parameters, Pattern, - PatternArguments, PatternKeyword, Singleton, Stmt, TypeParam, TypeParams, UnaryOp, WithItem, + Alias, Arguments, BoolOp, BytesLiteral, CmpOp, Comprehension, Decorator, ElifElseClause, + ExceptHandler, Expr, FString, FStringElement, Keyword, MatchCase, Mod, Operator, Parameter, + ParameterWithDefault, Parameters, Pattern, PatternArguments, PatternKeyword, Singleton, Stmt, + StringLiteral, TypeParam, TypeParams, UnaryOp, WithItem, }; use crate::{AnyNodeRef, AstNode}; @@ -73,11 +74,6 @@ pub trait PreorderVisitor<'a> { walk_except_handler(self, except_handler); } - #[inline] - fn visit_format_spec(&mut self, format_spec: &'a Expr) { - walk_format_spec(self, format_spec); - } - #[inline] fn visit_arguments(&mut self, arguments: &'a Arguments) { walk_arguments(self, arguments); @@ -138,7 +134,6 @@ pub trait PreorderVisitor<'a> { } #[inline] - fn visit_pattern_keyword(&mut self, pattern_keyword: &'a PatternKeyword) { walk_pattern_keyword(self, pattern_keyword); } @@ -152,6 +147,26 @@ pub trait PreorderVisitor<'a> { fn visit_elif_else_clause(&mut self, elif_else_clause: &'a ElifElseClause) { walk_elif_else_clause(self, elif_else_clause); } + + #[inline] + fn visit_f_string(&mut self, f_string: &'a FString) { + walk_f_string(self, f_string); + } + + #[inline] + fn visit_f_string_element(&mut self, f_string_element: &'a FStringElement) { + walk_f_string_element(self, f_string_element); + } + + #[inline] + fn visit_string_literal(&mut self, string_literal: &'a StringLiteral) { + walk_string_literal(self, string_literal); + } + + #[inline] + fn visit_bytes_literal(&mut self, bytes_literal: &'a BytesLiteral) { + walk_bytes_literal(self, bytes_literal); + } } pub fn walk_module<'a, V>(visitor: &mut V, module: &'a Mod) @@ -274,7 +289,6 @@ where Expr::YieldFrom(expr) => expr.visit_preorder(visitor), Expr::Compare(expr) => expr.visit_preorder(visitor), Expr::Call(expr) => expr.visit_preorder(visitor), - Expr::FormattedValue(expr) => expr.visit_preorder(visitor), Expr::FString(expr) => expr.visit_preorder(visitor), Expr::StringLiteral(expr) => expr.visit_preorder(visitor), Expr::BytesLiteral(expr) => expr.visit_preorder(visitor), @@ -503,6 +517,20 @@ where visitor.leave_node(node); } +pub fn walk_f_string_element<'a, V: PreorderVisitor<'a> + ?Sized>( + visitor: &mut V, + f_string_element: &'a FStringElement, +) { + let node = AnyNodeRef::from(f_string_element); + if visitor.enter_node(node).is_traverse() { + match f_string_element { + FStringElement::Expression(element) => element.visit_preorder(visitor), + FStringElement::Literal(element) => element.visit_preorder(visitor), + } + } + visitor.leave_node(node); +} + pub fn walk_bool_op<'a, V>(_visitor: &mut V, _bool_op: &'a BoolOp) where V: PreorderVisitor<'a> + ?Sized, @@ -530,6 +558,42 @@ where { } +#[inline] +pub fn walk_f_string<'a, V>(visitor: &mut V, f_string: &'a FString) +where + V: PreorderVisitor<'a> + ?Sized, +{ + let node = AnyNodeRef::from(f_string); + if visitor.enter_node(node).is_traverse() { + f_string.visit_preorder(visitor); + } + visitor.leave_node(node); +} + +#[inline] +pub fn walk_string_literal<'a, V>(visitor: &mut V, string_literal: &'a StringLiteral) +where + V: PreorderVisitor<'a> + ?Sized, +{ + let node = AnyNodeRef::from(string_literal); + if visitor.enter_node(node).is_traverse() { + string_literal.visit_preorder(visitor); + } + visitor.leave_node(node); +} + +#[inline] +pub fn walk_bytes_literal<'a, V>(visitor: &mut V, bytes_literal: &'a BytesLiteral) +where + V: PreorderVisitor<'a> + ?Sized, +{ + let node = AnyNodeRef::from(bytes_literal); + if visitor.enter_node(node).is_traverse() { + bytes_literal.visit_preorder(visitor); + } + visitor.leave_node(node); +} + #[inline] pub fn walk_alias<'a, V>(visitor: &mut V, alias: &'a Alias) where diff --git a/crates/ruff_python_ast/src/visitor/transformer.rs b/crates/ruff_python_ast/src/visitor/transformer.rs index b90ab0a1b61e9..caa111c43f95b 100644 --- a/crates/ruff_python_ast/src/visitor/transformer.rs +++ b/crates/ruff_python_ast/src/visitor/transformer.rs @@ -1,8 +1,8 @@ use crate::{ - self as ast, Alias, Arguments, BoolOp, CmpOp, Comprehension, Decorator, ElifElseClause, - ExceptHandler, Expr, ExprContext, Keyword, MatchCase, Operator, Parameter, Parameters, Pattern, - PatternArguments, PatternKeyword, Stmt, TypeParam, TypeParamTypeVar, TypeParams, UnaryOp, - WithItem, + self as ast, Alias, Arguments, BoolOp, BytesLiteral, CmpOp, Comprehension, Decorator, + ElifElseClause, ExceptHandler, Expr, ExprContext, FString, FStringElement, Keyword, MatchCase, + Operator, Parameter, Parameters, Pattern, PatternArguments, PatternKeyword, Stmt, + StringLiteral, TypeParam, TypeParamTypeVar, TypeParams, UnaryOp, WithItem, }; /// A trait for transforming ASTs. Visits all nodes in the AST recursively in evaluation-order. @@ -40,9 +40,6 @@ pub trait Transformer { fn visit_except_handler(&self, except_handler: &mut ExceptHandler) { walk_except_handler(self, except_handler); } - fn visit_format_spec(&self, format_spec: &mut Expr) { - walk_format_spec(self, format_spec); - } fn visit_arguments(&self, arguments: &mut Arguments) { walk_arguments(self, arguments); } @@ -85,6 +82,18 @@ pub trait Transformer { fn visit_elif_else_clause(&self, elif_else_clause: &mut ElifElseClause) { walk_elif_else_clause(self, elif_else_clause); } + fn visit_f_string(&self, f_string: &mut FString) { + walk_f_string(self, f_string); + } + fn visit_f_string_element(&self, f_string_element: &mut FStringElement) { + walk_f_string_element(self, f_string_element); + } + fn visit_string_literal(&self, string_literal: &mut StringLiteral) { + walk_string_literal(self, string_literal); + } + fn visit_bytes_literal(&self, bytes_literal: &mut BytesLiteral) { + walk_bytes_literal(self, bytes_literal); + } } pub fn walk_body(visitor: &V, body: &mut [Stmt]) { @@ -454,22 +463,29 @@ pub fn walk_expr(visitor: &V, expr: &mut Expr) { visitor.visit_expr(func); visitor.visit_arguments(arguments); } - Expr::FormattedValue(ast::ExprFormattedValue { - value, format_spec, .. - }) => { - visitor.visit_expr(value); - if let Some(expr) = format_spec { - visitor.visit_format_spec(expr); + Expr::FString(ast::ExprFString { value, .. }) => { + for f_string_part in value.iter_mut() { + match f_string_part { + ast::FStringPart::Literal(string_literal) => { + visitor.visit_string_literal(string_literal); + } + ast::FStringPart::FString(f_string) => { + visitor.visit_f_string(f_string); + } + } } } - Expr::FString(ast::ExprFString { values, .. }) => { - for expr in values { - visitor.visit_expr(expr); + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { + for string_literal in value.iter_mut() { + visitor.visit_string_literal(string_literal); + } + } + Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => { + for bytes_literal in value.iter_mut() { + visitor.visit_bytes_literal(bytes_literal); } } - Expr::StringLiteral(_) - | Expr::BytesLiteral(_) - | Expr::NumberLiteral(_) + Expr::NumberLiteral(_) | Expr::BooleanLiteral(_) | Expr::NoneLiteral(_) | Expr::EllipsisLiteral(_) => {} @@ -560,10 +576,6 @@ pub fn walk_except_handler( } } -pub fn walk_format_spec(visitor: &V, format_spec: &mut Expr) { - visitor.visit_expr(format_spec); -} - pub fn walk_arguments(visitor: &V, arguments: &mut Arguments) { // Note that the there might be keywords before the last arg, e.g. in // f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then @@ -713,20 +725,51 @@ pub fn walk_pattern_keyword( visitor.visit_pattern(&mut pattern_keyword.pattern); } -#[allow(unused_variables)] -pub fn walk_expr_context(visitor: &V, expr_context: &mut ExprContext) {} +pub fn walk_f_string(visitor: &V, f_string: &mut FString) { + for element in &mut f_string.elements { + visitor.visit_f_string_element(element); + } +} + +pub fn walk_f_string_element( + visitor: &V, + f_string_element: &mut FStringElement, +) { + if let ast::FStringElement::Expression(ast::FStringExpressionElement { + expression, + format_spec, + .. + }) = f_string_element + { + visitor.visit_expr(expression); + if let Some(format_spec) = format_spec { + for spec_element in &mut format_spec.elements { + visitor.visit_f_string_element(spec_element); + } + } + } +} -#[allow(unused_variables)] -pub fn walk_bool_op(visitor: &V, bool_op: &mut BoolOp) {} +pub fn walk_expr_context(_visitor: &V, _expr_context: &mut ExprContext) {} -#[allow(unused_variables)] -pub fn walk_operator(visitor: &V, operator: &mut Operator) {} +pub fn walk_bool_op(_visitor: &V, _bool_op: &mut BoolOp) {} -#[allow(unused_variables)] -pub fn walk_unary_op(visitor: &V, unary_op: &mut UnaryOp) {} +pub fn walk_operator(_visitor: &V, _operator: &mut Operator) {} -#[allow(unused_variables)] -pub fn walk_cmp_op(visitor: &V, cmp_op: &mut CmpOp) {} +pub fn walk_unary_op(_visitor: &V, _unary_op: &mut UnaryOp) {} -#[allow(unused_variables)] -pub fn walk_alias(visitor: &V, alias: &mut Alias) {} +pub fn walk_cmp_op(_visitor: &V, _cmp_op: &mut CmpOp) {} + +pub fn walk_alias(_visitor: &V, _alias: &mut Alias) {} + +pub fn walk_string_literal( + _visitor: &V, + _string_literal: &mut StringLiteral, +) { +} + +pub fn walk_bytes_literal( + _visitor: &V, + _bytes_literal: &mut BytesLiteral, +) { +} diff --git a/crates/ruff_python_ast/tests/preorder.rs b/crates/ruff_python_ast/tests/preorder.rs index 106ce9138967c..ea0542d9f1e6f 100644 --- a/crates/ruff_python_ast/tests/preorder.rs +++ b/crates/ruff_python_ast/tests/preorder.rs @@ -2,16 +2,8 @@ use std::fmt::{Debug, Write}; use insta::assert_snapshot; -use ruff_python_ast::visitor::preorder::{ - walk_alias, walk_comprehension, walk_except_handler, walk_expr, walk_keyword, walk_match_case, - walk_module, walk_parameter, walk_parameters, walk_pattern, walk_stmt, walk_type_param, - walk_with_item, PreorderVisitor, -}; -use ruff_python_ast::AnyNodeRef; -use ruff_python_ast::{ - Alias, BoolOp, CmpOp, Comprehension, ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, - Parameter, Parameters, Pattern, Singleton, Stmt, TypeParam, UnaryOp, WithItem, -}; +use ruff_python_ast::visitor::preorder::{PreorderVisitor, TraversalSignal}; +use ruff_python_ast::{AnyNodeRef, BoolOp, CmpOp, Operator, Singleton, UnaryOp}; use ruff_python_parser::lexer::lex; use ruff_python_parser::{parse_tokens, Mode}; @@ -128,6 +120,33 @@ fn function_type_parameters() { assert_snapshot!(trace); } +#[test] +fn string_literals() { + let source = r"'a' 'b' 'c'"; + + let trace = trace_preorder_visitation(source); + + assert_snapshot!(trace); +} + +#[test] +fn bytes_literals() { + let source = r"b'a' b'b' b'c'"; + + let trace = trace_preorder_visitation(source); + + assert_snapshot!(trace); +} + +#[test] +fn f_strings() { + let source = r"'pre' f'foo {bar:.{x}f} baz'"; + + let trace = trace_preorder_visitation(source); + + assert_snapshot!(trace); +} + fn trace_preorder_visitation(source: &str) -> String { let tokens = lex(source, Mode::Module); let parsed = parse_tokens(tokens, source, Mode::Module, "test.py").unwrap(); @@ -147,18 +166,6 @@ struct RecordVisitor { } impl RecordVisitor { - fn enter_node<'a, T>(&mut self, node: T) - where - T: Into>, - { - self.emit(&node.into().kind()); - self.depth += 1; - } - - fn exit_node(&mut self) { - self.depth -= 1; - } - fn emit(&mut self, text: &dyn Debug) { for _ in 0..self.depth { self.output.push_str(" "); @@ -168,29 +175,16 @@ impl RecordVisitor { } } -impl PreorderVisitor<'_> for RecordVisitor { - fn visit_mod(&mut self, module: &Mod) { - self.enter_node(module); - walk_module(self, module); - self.exit_node(); - } - - fn visit_stmt(&mut self, stmt: &Stmt) { - self.enter_node(stmt); - walk_stmt(self, stmt); - self.exit_node(); - } +impl<'a> PreorderVisitor<'a> for RecordVisitor { + fn enter_node(&mut self, node: AnyNodeRef<'a>) -> TraversalSignal { + self.emit(&node.kind()); + self.depth += 1; - fn visit_annotation(&mut self, expr: &Expr) { - self.enter_node(expr); - walk_expr(self, expr); - self.exit_node(); + TraversalSignal::Traverse } - fn visit_expr(&mut self, expr: &Expr) { - self.enter_node(expr); - walk_expr(self, expr); - self.exit_node(); + fn leave_node(&mut self, _node: AnyNodeRef<'a>) { + self.depth -= 1; } fn visit_singleton(&mut self, singleton: &Singleton) { @@ -212,70 +206,4 @@ impl PreorderVisitor<'_> for RecordVisitor { fn visit_cmp_op(&mut self, cmp_op: &CmpOp) { self.emit(&cmp_op); } - - fn visit_comprehension(&mut self, comprehension: &Comprehension) { - self.enter_node(comprehension); - walk_comprehension(self, comprehension); - self.exit_node(); - } - - fn visit_except_handler(&mut self, except_handler: &ExceptHandler) { - self.enter_node(except_handler); - walk_except_handler(self, except_handler); - self.exit_node(); - } - - fn visit_format_spec(&mut self, format_spec: &Expr) { - self.enter_node(format_spec); - walk_expr(self, format_spec); - self.exit_node(); - } - - fn visit_parameters(&mut self, parameters: &Parameters) { - self.enter_node(parameters); - walk_parameters(self, parameters); - self.exit_node(); - } - - fn visit_parameter(&mut self, parameter: &Parameter) { - self.enter_node(parameter); - walk_parameter(self, parameter); - self.exit_node(); - } - - fn visit_keyword(&mut self, keyword: &Keyword) { - self.enter_node(keyword); - walk_keyword(self, keyword); - self.exit_node(); - } - - fn visit_alias(&mut self, alias: &Alias) { - self.enter_node(alias); - walk_alias(self, alias); - self.exit_node(); - } - - fn visit_with_item(&mut self, with_item: &WithItem) { - self.enter_node(with_item); - walk_with_item(self, with_item); - self.exit_node(); - } - - fn visit_match_case(&mut self, match_case: &MatchCase) { - self.enter_node(match_case); - walk_match_case(self, match_case); - self.exit_node(); - } - - fn visit_pattern(&mut self, pattern: &Pattern) { - self.enter_node(pattern); - walk_pattern(self, pattern); - self.exit_node(); - } - - fn visit_type_param(&mut self, type_param: &TypeParam) { - self.enter_node(type_param); - walk_type_param(self, type_param); - self.exit_node(); - } } diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__bytes_literals.snap b/crates/ruff_python_ast/tests/snapshots/preorder__bytes_literals.snap new file mode 100644 index 0000000000000..d71ea07e19274 --- /dev/null +++ b/crates/ruff_python_ast/tests/snapshots/preorder__bytes_literals.snap @@ -0,0 +1,11 @@ +--- +source: crates/ruff_python_ast/tests/preorder.rs +expression: trace +--- +- ModModule + - StmtExpr + - ExprBytesLiteral + - BytesLiteral + - BytesLiteral + - BytesLiteral + diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__class_type_parameters.snap b/crates/ruff_python_ast/tests/snapshots/preorder__class_type_parameters.snap index bf2a7eccb5fe4..20ef6b71fa442 100644 --- a/crates/ruff_python_ast/tests/snapshots/preorder__class_type_parameters.snap +++ b/crates/ruff_python_ast/tests/snapshots/preorder__class_type_parameters.snap @@ -4,11 +4,12 @@ expression: trace --- - ModModule - StmtClassDef - - TypeParamTypeVar - - ExprName - - TypeParamTypeVar - - TypeParamTypeVarTuple - - TypeParamParamSpec + - TypeParams + - TypeParamTypeVar + - ExprName + - TypeParamTypeVar + - TypeParamTypeVarTuple + - TypeParamParamSpec - StmtExpr - ExprEllipsisLiteral diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__decorators.snap b/crates/ruff_python_ast/tests/snapshots/preorder__decorators.snap index ff57b138dec47..e91bd2e83b9bb 100644 --- a/crates/ruff_python_ast/tests/snapshots/preorder__decorators.snap +++ b/crates/ruff_python_ast/tests/snapshots/preorder__decorators.snap @@ -4,10 +4,12 @@ expression: trace --- - ModModule - StmtFunctionDef - - ExprName + - Decorator + - ExprName - Parameters - StmtPass - StmtClassDef - - ExprName + - Decorator + - ExprName - StmtPass diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__f_strings.snap b/crates/ruff_python_ast/tests/snapshots/preorder__f_strings.snap new file mode 100644 index 0000000000000..043c58064b48e --- /dev/null +++ b/crates/ruff_python_ast/tests/snapshots/preorder__f_strings.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_python_ast/tests/preorder.rs +expression: trace +--- +- ModModule + - StmtExpr + - ExprFString + - StringLiteral + - FString + - FStringLiteralElement + - FStringExpressionElement + - ExprName + - FStringLiteralElement + - FStringExpressionElement + - ExprName + - FStringLiteralElement + - FStringLiteralElement + diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__function_arguments.snap b/crates/ruff_python_ast/tests/snapshots/preorder__function_arguments.snap index 5ecec46ee04f9..da83fc10f8129 100644 --- a/crates/ruff_python_ast/tests/snapshots/preorder__function_arguments.snap +++ b/crates/ruff_python_ast/tests/snapshots/preorder__function_arguments.snap @@ -5,16 +5,22 @@ expression: trace - ModModule - StmtFunctionDef - Parameters - - Parameter - - Parameter - - Parameter - - Parameter - - ExprNumberLiteral - - Parameter - - Parameter - - ExprNumberLiteral - - Parameter - - ExprNumberLiteral + - ParameterWithDefault + - Parameter + - ParameterWithDefault + - Parameter + - ParameterWithDefault + - Parameter + - ParameterWithDefault + - Parameter + - ExprNumberLiteral + - Parameter + - ParameterWithDefault + - Parameter + - ExprNumberLiteral + - ParameterWithDefault + - Parameter + - ExprNumberLiteral - Parameter - StmtPass diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__function_positional_only_with_default.snap b/crates/ruff_python_ast/tests/snapshots/preorder__function_positional_only_with_default.snap index fdc755b1f0270..6511aa3468297 100644 --- a/crates/ruff_python_ast/tests/snapshots/preorder__function_positional_only_with_default.snap +++ b/crates/ruff_python_ast/tests/snapshots/preorder__function_positional_only_with_default.snap @@ -5,11 +5,14 @@ expression: trace - ModModule - StmtFunctionDef - Parameters - - Parameter - - Parameter - - ExprNumberLiteral - - Parameter - - ExprNumberLiteral + - ParameterWithDefault + - Parameter + - ParameterWithDefault + - Parameter + - ExprNumberLiteral + - ParameterWithDefault + - Parameter + - ExprNumberLiteral - Parameter - StmtPass diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__function_type_parameters.snap b/crates/ruff_python_ast/tests/snapshots/preorder__function_type_parameters.snap index 47aa1ecf6a7f5..11b98d0fa78e3 100644 --- a/crates/ruff_python_ast/tests/snapshots/preorder__function_type_parameters.snap +++ b/crates/ruff_python_ast/tests/snapshots/preorder__function_type_parameters.snap @@ -4,11 +4,12 @@ expression: trace --- - ModModule - StmtFunctionDef - - TypeParamTypeVar - - ExprName - - TypeParamTypeVar - - TypeParamTypeVarTuple - - TypeParamParamSpec + - TypeParams + - TypeParamTypeVar + - ExprName + - TypeParamTypeVar + - TypeParamTypeVarTuple + - TypeParamParamSpec - Parameters - StmtExpr - ExprEllipsisLiteral diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__match_class_pattern.snap b/crates/ruff_python_ast/tests/snapshots/preorder__match_class_pattern.snap index da4fe2cd9750c..dbe56f11ff3bd 100644 --- a/crates/ruff_python_ast/tests/snapshots/preorder__match_class_pattern.snap +++ b/crates/ruff_python_ast/tests/snapshots/preorder__match_class_pattern.snap @@ -8,21 +8,26 @@ expression: trace - MatchCase - PatternMatchClass - ExprName - - PatternMatchValue - - ExprNumberLiteral - - PatternMatchValue - - ExprNumberLiteral + - PatternArguments + - PatternMatchValue + - ExprNumberLiteral + - PatternMatchValue + - ExprNumberLiteral - StmtExpr - ExprEllipsisLiteral - MatchCase - PatternMatchClass - ExprName - - PatternMatchValue - - ExprNumberLiteral - - PatternMatchValue - - ExprNumberLiteral - - PatternMatchValue - - ExprNumberLiteral + - PatternArguments + - PatternKeyword + - PatternMatchValue + - ExprNumberLiteral + - PatternKeyword + - PatternMatchValue + - ExprNumberLiteral + - PatternKeyword + - PatternMatchValue + - ExprNumberLiteral - StmtExpr - ExprEllipsisLiteral diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__string_literals.snap b/crates/ruff_python_ast/tests/snapshots/preorder__string_literals.snap new file mode 100644 index 0000000000000..7b62ce78b72f7 --- /dev/null +++ b/crates/ruff_python_ast/tests/snapshots/preorder__string_literals.snap @@ -0,0 +1,11 @@ +--- +source: crates/ruff_python_ast/tests/preorder.rs +expression: trace +--- +- ModModule + - StmtExpr + - ExprStringLiteral + - StringLiteral + - StringLiteral + - StringLiteral + diff --git a/crates/ruff_python_ast/tests/snapshots/preorder__type_aliases.snap b/crates/ruff_python_ast/tests/snapshots/preorder__type_aliases.snap index 56c170d9b8558..56d6aec5c0dec 100644 --- a/crates/ruff_python_ast/tests/snapshots/preorder__type_aliases.snap +++ b/crates/ruff_python_ast/tests/snapshots/preorder__type_aliases.snap @@ -5,11 +5,12 @@ expression: trace - ModModule - StmtTypeAlias - ExprName - - TypeParamTypeVar - - ExprName - - TypeParamTypeVar - - TypeParamTypeVarTuple - - TypeParamParamSpec + - TypeParams + - TypeParamTypeVar + - ExprName + - TypeParamTypeVar + - TypeParamTypeVarTuple + - TypeParamParamSpec - ExprSubscript - ExprName - ExprName diff --git a/crates/ruff_python_ast/tests/snapshots/visitor__bytes_literals.snap b/crates/ruff_python_ast/tests/snapshots/visitor__bytes_literals.snap new file mode 100644 index 0000000000000..57bed3a9c7502 --- /dev/null +++ b/crates/ruff_python_ast/tests/snapshots/visitor__bytes_literals.snap @@ -0,0 +1,10 @@ +--- +source: crates/ruff_python_ast/tests/visitor.rs +expression: trace +--- +- StmtExpr + - ExprBytesLiteral + - BytesLiteral + - BytesLiteral + - BytesLiteral + diff --git a/crates/ruff_python_ast/tests/snapshots/visitor__f_strings.snap b/crates/ruff_python_ast/tests/snapshots/visitor__f_strings.snap new file mode 100644 index 0000000000000..a5c8a8b905927 --- /dev/null +++ b/crates/ruff_python_ast/tests/snapshots/visitor__f_strings.snap @@ -0,0 +1,17 @@ +--- +source: crates/ruff_python_ast/tests/visitor.rs +expression: trace +--- +- StmtExpr + - ExprFString + - StringLiteral + - FString + - FStringLiteralElement + - FStringExpressionElement + - ExprName + - FStringLiteralElement + - FStringExpressionElement + - ExprName + - FStringLiteralElement + - FStringLiteralElement + diff --git a/crates/ruff_python_ast/tests/snapshots/visitor__string_literals.snap b/crates/ruff_python_ast/tests/snapshots/visitor__string_literals.snap new file mode 100644 index 0000000000000..7c066eae56989 --- /dev/null +++ b/crates/ruff_python_ast/tests/snapshots/visitor__string_literals.snap @@ -0,0 +1,10 @@ +--- +source: crates/ruff_python_ast/tests/visitor.rs +expression: trace +--- +- StmtExpr + - ExprStringLiteral + - StringLiteral + - StringLiteral + - StringLiteral + diff --git a/crates/ruff_python_ast/tests/visitor.rs b/crates/ruff_python_ast/tests/visitor.rs index a503009566f78..46af0903b6fcf 100644 --- a/crates/ruff_python_ast/tests/visitor.rs +++ b/crates/ruff_python_ast/tests/visitor.rs @@ -6,14 +6,16 @@ use ruff_python_parser::lexer::lex; use ruff_python_parser::{parse_tokens, Mode}; use ruff_python_ast::visitor::{ - walk_alias, walk_comprehension, walk_except_handler, walk_expr, walk_keyword, walk_match_case, - walk_parameter, walk_parameters, walk_pattern, walk_stmt, walk_type_param, walk_with_item, + walk_alias, walk_bytes_literal, walk_comprehension, walk_except_handler, walk_expr, + walk_f_string, walk_f_string_element, walk_keyword, walk_match_case, walk_parameter, + walk_parameters, walk_pattern, walk_stmt, walk_string_literal, walk_type_param, walk_with_item, Visitor, }; use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{ - Alias, BoolOp, CmpOp, Comprehension, ExceptHandler, Expr, Keyword, MatchCase, Operator, - Parameter, Parameters, Pattern, Stmt, TypeParam, UnaryOp, WithItem, + Alias, BoolOp, BytesLiteral, CmpOp, Comprehension, ExceptHandler, Expr, FString, + FStringElement, Keyword, MatchCase, Operator, Parameter, Parameters, Pattern, Stmt, + StringLiteral, TypeParam, UnaryOp, WithItem, }; #[test] @@ -129,6 +131,33 @@ fn function_type_parameters() { assert_snapshot!(trace); } +#[test] +fn string_literals() { + let source = r"'a' 'b' 'c'"; + + let trace = trace_visitation(source); + + assert_snapshot!(trace); +} + +#[test] +fn bytes_literals() { + let source = r"b'a' b'b' b'c'"; + + let trace = trace_visitation(source); + + assert_snapshot!(trace); +} + +#[test] +fn f_strings() { + let source = r"'pre' f'foo {bar:.{x}f} baz'"; + + let trace = trace_visitation(source); + + assert_snapshot!(trace); +} + fn trace_visitation(source: &str) -> String { let tokens = lex(source, Mode::Module); let parsed = parse_tokens(tokens, source, Mode::Module, "test.py").unwrap(); @@ -228,12 +257,6 @@ impl Visitor<'_> for RecordVisitor { self.exit_node(); } - fn visit_format_spec(&mut self, format_spec: &Expr) { - self.enter_node(format_spec); - walk_expr(self, format_spec); - self.exit_node(); - } - fn visit_parameters(&mut self, parameters: &Parameters) { self.enter_node(parameters); walk_parameters(self, parameters); @@ -281,4 +304,28 @@ impl Visitor<'_> for RecordVisitor { walk_type_param(self, type_param); self.exit_node(); } + + fn visit_string_literal(&mut self, string_literal: &StringLiteral) { + self.enter_node(string_literal); + walk_string_literal(self, string_literal); + self.exit_node(); + } + + fn visit_bytes_literal(&mut self, bytes_literal: &BytesLiteral) { + self.enter_node(bytes_literal); + walk_bytes_literal(self, bytes_literal); + self.exit_node(); + } + + fn visit_f_string(&mut self, f_string: &FString) { + self.enter_node(f_string); + walk_f_string(self, f_string); + self.exit_node(); + } + + fn visit_f_string_element(&mut self, f_string_element: &FStringElement) { + self.enter_node(f_string_element); + walk_f_string_element(self, f_string_element); + self.exit_node(); + } } diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 3c83bc26d9300..7f9d5d4f8e2a8 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -1069,29 +1069,18 @@ impl<'a> Generator<'a> { } self.p(")"); } - Expr::FormattedValue(ast::ExprFormattedValue { - value, - debug_text, - conversion, - format_spec, - range: _, - }) => self.unparse_formatted( - value, - debug_text.as_ref(), - *conversion, - format_spec.as_deref(), - ), - Expr::FString(ast::ExprFString { values, .. }) => { - self.unparse_f_string(values, false); + Expr::FString(ast::ExprFString { value, .. }) => { + self.unparse_f_string_value(value, false); } - Expr::StringLiteral(ast::ExprStringLiteral { value, unicode, .. }) => { - if *unicode { - self.p("u"); - } - self.p_str_repr(value); + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { + self.unparse_string_literal_value(value); } Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => { - self.p_bytes_repr(value); + let mut first = true; + for bytes_literal in value { + self.p_delim(&mut first, " "); + self.p_bytes_repr(&bytes_literal.value); + } } Expr::NumberLiteral(ast::ExprNumberLiteral { value, .. }) => { static INF_STR: &str = "1e309"; @@ -1275,18 +1264,48 @@ impl<'a> Generator<'a> { } } - fn unparse_f_string_body(&mut self, values: &[Expr], is_spec: bool) { + fn unparse_string_literal(&mut self, string_literal: &ast::StringLiteral) { + if string_literal.unicode { + self.p("u"); + } + self.p_str_repr(&string_literal.value); + } + + fn unparse_string_literal_value(&mut self, value: &ast::StringLiteralValue) { + let mut first = true; + for string_literal in value { + self.p_delim(&mut first, " "); + self.unparse_string_literal(string_literal); + } + } + + fn unparse_f_string_value(&mut self, value: &ast::FStringValue, is_spec: bool) { + let mut first = true; + for f_string_part in value { + self.p_delim(&mut first, " "); + match f_string_part { + ast::FStringPart::Literal(string_literal) => { + self.unparse_string_literal(string_literal); + } + ast::FStringPart::FString(f_string) => { + self.unparse_f_string(&f_string.elements, is_spec); + } + } + } + } + + fn unparse_f_string_body(&mut self, values: &[ast::FStringElement]) { for value in values { - self.unparse_f_string_elem(value, is_spec); + self.unparse_f_string_element(value); } } - fn unparse_formatted( + fn unparse_f_string_expression_element( &mut self, val: &Expr, debug_text: Option<&DebugText>, conversion: ConversionFlag, - spec: Option<&Expr>, + spec: Option<&ast::FStringFormatSpec>, ) { let mut generator = Generator::new(self.indent, self.quote, self.line_ending); generator.unparse_expr(val, precedence::FORMATTED_VALUE); @@ -1316,44 +1335,40 @@ impl<'a> Generator<'a> { if let Some(spec) = spec { self.p(":"); - self.unparse_f_string_elem(spec, true); + self.unparse_f_string(&spec.elements, true); } self.p("}"); } - fn unparse_f_string_elem(&mut self, expr: &Expr, is_spec: bool) { - match expr { - Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => { - self.unparse_f_string_literal(value); + fn unparse_f_string_element(&mut self, element: &ast::FStringElement) { + match element { + ast::FStringElement::Literal(ast::FStringLiteralElement { value, .. }) => { + self.unparse_f_string_literal_element(value); } - Expr::FString(ast::ExprFString { values, .. }) => { - self.unparse_f_string(values, is_spec); - } - Expr::FormattedValue(ast::ExprFormattedValue { - value, + ast::FStringElement::Expression(ast::FStringExpressionElement { + expression, debug_text, conversion, format_spec, range: _, - }) => self.unparse_formatted( - value, + }) => self.unparse_f_string_expression_element( + expression, debug_text.as_ref(), *conversion, format_spec.as_deref(), ), - _ => unreachable!(), } } - fn unparse_f_string_literal(&mut self, s: &str) { + fn unparse_f_string_literal_element(&mut self, s: &str) { let s = s.replace('{', "{{").replace('}', "}}"); self.p(&s); } - fn unparse_f_string(&mut self, values: &[Expr], is_spec: bool) { + fn unparse_f_string(&mut self, values: &[ast::FStringElement], is_spec: bool) { if is_spec { - self.unparse_f_string_body(values, is_spec); + self.unparse_f_string_body(values); } else { self.p("f"); let mut generator = Generator::new( @@ -1364,7 +1379,7 @@ impl<'a> Generator<'a> { }, self.line_ending, ); - generator.unparse_f_string_body(values, is_spec); + generator.unparse_f_string_body(values); let body = &generator.buffer; self.p_str_repr(body); } @@ -1678,14 +1693,14 @@ class Foo: assert_eq!(round_trip(r"u'hello'"), r#"u"hello""#); assert_eq!(round_trip(r"r'hello'"), r#""hello""#); assert_eq!(round_trip(r"b'hello'"), r#"b"hello""#); - assert_eq!(round_trip(r#"("abc" "def" "ghi")"#), r#""abcdefghi""#); + assert_eq!(round_trip(r#"("abc" "def" "ghi")"#), r#""abc" "def" "ghi""#); assert_eq!(round_trip(r#""he\"llo""#), r#"'he"llo'"#); assert_eq!(round_trip(r#"f"abc{'def'}{1}""#), r#"f"abc{'def'}{1}""#); assert_eq!(round_trip(r#"f'abc{"def"}{1}'"#), r#"f"abc{'def'}{1}""#); } #[test] - fn self_documenting_f_string() { + fn self_documenting_fstring() { assert_round_trip!(r#"f"{ chr(65) = }""#); assert_round_trip!(r#"f"{ chr(65) = !s}""#); assert_round_trip!(r#"f"{ chr(65) = !r}""#); @@ -1693,6 +1708,13 @@ class Foo: assert_round_trip!(r#"f"{a=!r:0.05f}""#); } + #[test] + fn implicit_string_concatenation() { + assert_round_trip!(r#""first" "second" "third""#); + assert_round_trip!(r#"b"first" b"second" b"third""#); + assert_round_trip!(r#""first" "second" f"third {var}""#); + } + #[test] fn indent() { assert_eq!( diff --git a/crates/ruff_python_formatter/CONTRIBUTING.md b/crates/ruff_python_formatter/CONTRIBUTING.md index c302a4dc49ba8..193ff8ef32004 100644 --- a/crates/ruff_python_formatter/CONTRIBUTING.md +++ b/crates/ruff_python_formatter/CONTRIBUTING.md @@ -218,7 +218,7 @@ call, for single items `.format().fmt(f)` or `.fmt(f)` is sufficient. impl FormatNodeRule for FormatStmtReturn { fn fmt_fields(&self, item: &StmtReturn, f: &mut PyFormatter) -> FormatResult<()> { // Here we destructure item and make sure each field is listed. - // We generally don't need range is it's underscore-ignored + // We generally don't need range if it's underscore-ignored let StmtReturn { range: _, value } = item; // Implement some formatting logic, in this case no space (and no value) after a return with // no value diff --git a/crates/ruff_python_formatter/Cargo.toml b/crates/ruff_python_formatter/Cargo.toml index 24325082f0f99..1c8825b3aff35 100644 --- a/crates/ruff_python_formatter/Cargo.toml +++ b/crates/ruff_python_formatter/Cargo.toml @@ -28,6 +28,7 @@ countme = "3.0.1" itertools = { workspace = true } memchr = { workspace = true } once_cell = { workspace = true } +regex = { workspace = true } rustc-hash = { workspace = true } serde = { workspace = true, optional = true } schemars = { workspace = true, optional = true } @@ -41,6 +42,7 @@ unicode-width = { workspace = true } ruff_formatter = { path = "../ruff_formatter" } insta = { workspace = true, features = ["glob"] } +regex = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } similar = { workspace = true } diff --git a/crates/ruff_python_formatter/generate.py b/crates/ruff_python_formatter/generate.py index 52c256dd17767..bf89ac1a4b523 100755 --- a/crates/ruff_python_formatter/generate.py +++ b/crates/ruff_python_formatter/generate.py @@ -30,10 +30,20 @@ def rustfmt(code: str) -> str: node_lines = ( nodes_file.split("pub enum AnyNode {")[1].split("}")[0].strip().splitlines() ) -nodes = [ - node_line.split("(")[1].split(")")[0].split("::")[-1].split("<")[0] - for node_line in node_lines -] +nodes = [] +for node_line in node_lines: + node = node_line.split("(")[1].split(")")[0].split("::")[-1].split("<")[0] + # `FString` and `StringLiteral` has a custom implementation while the formatting for + # `FStringLiteralElement` and `FStringExpressionElement` are handled by the `FString` + # implementation. + if node in ( + "FString", + "StringLiteral", + "FStringLiteralElement", + "FStringExpressionElement", + ): + continue + nodes.append(node) print(nodes) # %% diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/attribute_access_on_number_literals.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/attribute_access_on_number_literals.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/attribute_access_on_number_literals.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/attribute_access_on_number_literals.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/attribute_access_on_number_literals.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/attribute_access_on_number_literals.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/attribute_access_on_number_literals.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/attribute_access_on_number_literals.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/beginning_backslash.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/beginning_backslash.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/beginning_backslash.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/beginning_backslash.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/beginning_backslash.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/beginning_backslash.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/beginning_backslash.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/beginning_backslash.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/bracketmatch.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/bracketmatch.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/bracketmatch.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/bracketmatch.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/bracketmatch.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/bracketmatch.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/bracketmatch.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/bracketmatch.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/bytes_docstring.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/bytes_docstring.py new file mode 100644 index 0000000000000..488aef1ed7649 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/bytes_docstring.py @@ -0,0 +1,14 @@ +def bitey(): + b" not a docstring" + +def bitey2(): + b' also not a docstring' + +def triple_quoted_bytes(): + b""" not a docstring""" + +def triple_quoted_bytes2(): + b''' also not a docstring''' + +def capitalized_bytes(): + B" NOT A DOCSTRING" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/bytes_docstring.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/bytes_docstring.py.expect new file mode 100644 index 0000000000000..d7ce57746e2be --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/bytes_docstring.py.expect @@ -0,0 +1,18 @@ +def bitey(): + b" not a docstring" + + +def bitey2(): + b" also not a docstring" + + +def triple_quoted_bytes(): + b""" not a docstring""" + + +def triple_quoted_bytes2(): + b""" also not a docstring""" + + +def capitalized_bytes(): + b" NOT A DOCSTRING" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_blank_parentheses.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/class_blank_parentheses.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_blank_parentheses.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/class_blank_parentheses.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_blank_parentheses.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/class_blank_parentheses.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_blank_parentheses.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/class_blank_parentheses.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_methods_new_line.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/class_methods_new_line.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_methods_new_line.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/class_methods_new_line.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_methods_new_line.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/class_methods_new_line.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/class_methods_new_line.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/class_methods_new_line.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/collections.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/collections.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/collections.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/collections.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/collections.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/collections.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/collections.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/collections.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comment_after_escaped_newline.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comment_after_escaped_newline.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comment_after_escaped_newline.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comment_after_escaped_newline.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comment_after_escaped_newline.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comment_after_escaped_newline.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comment_after_escaped_newline.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comment_after_escaped_newline.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments2.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments2.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments2.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments2.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments2.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments2.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments2.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments2.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments3.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments3.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments3.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments3.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments3.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments3.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments3.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments3.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments4.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments4.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments4.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments4.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments4.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments4.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments4.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments4.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments5.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments5.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments5.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments5.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments5.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments5.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments5.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments5.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments6.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments6.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments6.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments6.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments6.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments6.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments6.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments6.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments8.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments8.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments8.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments8.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments8.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments8.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments8.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments8.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments9.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments9.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments9.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments9.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments9.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments9.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments9.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments9.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_in_blocks.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_in_blocks.py new file mode 100644 index 0000000000000..1221139b6d818 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_in_blocks.py @@ -0,0 +1,111 @@ +# Test cases from: +# - https://github.com/psf/black/issues/1798 +# - https://github.com/psf/black/issues/1499 +# - https://github.com/psf/black/issues/1211 +# - https://github.com/psf/black/issues/563 + +( + lambda + # a comment + : None +) + +( + lambda: + # b comment + None +) + +( + lambda + # a comment + : + # b comment + None +) + +[ + x + # Let's do this + for + # OK? + x + # Some comment + # And another + in + # One more + y +] + +return [ + (offers[offer_index], 1.0) + for offer_index, _ + # avoid returning any offers that don't match the grammar so + # that the return values here are consistent with what would be + # returned in AcceptValidHeader + in self._parse_and_normalize_offers(offers) +] + +from foo import ( + bar, + # qux +) + + +def convert(collection): + # replace all variables by integers + replacement_dict = { + variable: f"{index}" + for index, variable + # 0 is reserved as line terminator + in enumerate(collection.variables(), start=1) + } + + +{ + i: i + for i + # a comment + in range(5) +} + + +def get_subtree_proof_nodes( + chunk_index_groups: Sequence[Tuple[int, ...], ...], +) -> Tuple[int, ...]: + subtree_node_paths = ( + # We take a candidate element from each group and shift it to + # remove the bits that are not common to other group members, then + # we convert it to a tree path that all elements from this group + # have in common. + chunk_index + for chunk_index, bits_to_truncate + # Each group will contain an even "power-of-two" number of# elements. + # This tells us how many tailing bits each element has# which need to + # be truncated to get the group's common prefix. + in ((group[0], (len(group) - 1).bit_length()) for group in chunk_index_groups) + ) + return subtree_node_paths + + +if ( + # comment1 + a + # comment2 + or ( + # comment3 + ( + # comment4 + b + ) + # comment5 + and + # comment6 + c + or ( + # comment7 + d + ) + ) +): + print("Foo") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_in_blocks.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_in_blocks.py.expect new file mode 100644 index 0000000000000..1221139b6d818 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_in_blocks.py.expect @@ -0,0 +1,111 @@ +# Test cases from: +# - https://github.com/psf/black/issues/1798 +# - https://github.com/psf/black/issues/1499 +# - https://github.com/psf/black/issues/1211 +# - https://github.com/psf/black/issues/563 + +( + lambda + # a comment + : None +) + +( + lambda: + # b comment + None +) + +( + lambda + # a comment + : + # b comment + None +) + +[ + x + # Let's do this + for + # OK? + x + # Some comment + # And another + in + # One more + y +] + +return [ + (offers[offer_index], 1.0) + for offer_index, _ + # avoid returning any offers that don't match the grammar so + # that the return values here are consistent with what would be + # returned in AcceptValidHeader + in self._parse_and_normalize_offers(offers) +] + +from foo import ( + bar, + # qux +) + + +def convert(collection): + # replace all variables by integers + replacement_dict = { + variable: f"{index}" + for index, variable + # 0 is reserved as line terminator + in enumerate(collection.variables(), start=1) + } + + +{ + i: i + for i + # a comment + in range(5) +} + + +def get_subtree_proof_nodes( + chunk_index_groups: Sequence[Tuple[int, ...], ...], +) -> Tuple[int, ...]: + subtree_node_paths = ( + # We take a candidate element from each group and shift it to + # remove the bits that are not common to other group members, then + # we convert it to a tree path that all elements from this group + # have in common. + chunk_index + for chunk_index, bits_to_truncate + # Each group will contain an even "power-of-two" number of# elements. + # This tells us how many tailing bits each element has# which need to + # be truncated to get the group's common prefix. + in ((group[0], (len(group) - 1).bit_length()) for group in chunk_index_groups) + ) + return subtree_node_paths + + +if ( + # comment1 + a + # comment2 + or ( + # comment3 + ( + # comment4 + b + ) + # comment5 + and + # comment6 + c + or ( + # comment7 + d + ) + ) +): + print("Foo") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments_non_breaking_space.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_non_breaking_space.py similarity index 90% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments_non_breaking_space.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_non_breaking_space.py index 0c5f5660ebba9..d1d42f025969c 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments_non_breaking_space.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_non_breaking_space.py @@ -14,6 +14,6 @@ def function(a:int=42): a b """ - #    There's a NBSP + 3 spaces before + #  There's a NBSP + 3 spaces before # And 4 spaces on the next line pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments_non_breaking_space.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_non_breaking_space.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments_non_breaking_space.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_non_breaking_space.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition_no_trailing_comma.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition_no_trailing_comma.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition_no_trailing_comma.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition_no_trailing_comma.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition_no_trailing_comma.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition_no_trailing_comma.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition_no_trailing_comma.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition_no_trailing_comma.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.py new file mode 100644 index 0000000000000..bbe56623c6107 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.py @@ -0,0 +1,67 @@ +long_kwargs_single_line = my_function( + foo="test, this is a sample value", + bar=some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz, + baz="hello, this is a another value", +) + +multiline_kwargs_indented = my_function( + foo="test, this is a sample value", + bar=some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz, + baz="hello, this is a another value", +) + +imploding_kwargs = my_function( + foo="test, this is a sample value", + bar=a + if foo + else b, + baz="hello, this is a another value", +) + +imploding_line = ( + 1 + if 1 + 1 == 2 + else 0 +) + +exploding_line = "hello this is a slightly long string" if some_long_value_name_foo_bar_baz else "this one is a little shorter" + +positional_argument_test(some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz) + +def weird_default_argument(x=some_long_value_name_foo_bar_baz + if SOME_CONSTANT + else some_fallback_value_foo_bar_baz): + pass + +nested = "hello this is a slightly long string" if (some_long_value_name_foo_bar_baz if + nesting_test_expressions else some_fallback_value_foo_bar_baz) \ + else "this one is a little shorter" + +generator_expression = ( + some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz for some_boolean_variable in some_iterable +) + + +def limit_offset_sql(self, low_mark, high_mark): + """Return LIMIT/OFFSET SQL clause.""" + limit, offset = self._get_limit_offset_params(low_mark, high_mark) + return " ".join( + sql + for sql in ( + "LIMIT %d" % limit if limit else None, + ("OFFSET %d" % offset) if offset else None, + ) + if sql + ) + + +def something(): + clone._iterable_class = ( + NamedValuesListIterable + if named + else FlatValuesListIterable + if flat + else ValuesListIterable + ) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.py.expect new file mode 100644 index 0000000000000..122ea7860dea7 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.py.expect @@ -0,0 +1,90 @@ +long_kwargs_single_line = my_function( + foo="test, this is a sample value", + bar=( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz + ), + baz="hello, this is a another value", +) + +multiline_kwargs_indented = my_function( + foo="test, this is a sample value", + bar=( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz + ), + baz="hello, this is a another value", +) + +imploding_kwargs = my_function( + foo="test, this is a sample value", + bar=a if foo else b, + baz="hello, this is a another value", +) + +imploding_line = 1 if 1 + 1 == 2 else 0 + +exploding_line = ( + "hello this is a slightly long string" + if some_long_value_name_foo_bar_baz + else "this one is a little shorter" +) + +positional_argument_test( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz +) + + +def weird_default_argument( + x=( + some_long_value_name_foo_bar_baz + if SOME_CONSTANT + else some_fallback_value_foo_bar_baz + ), +): + pass + + +nested = ( + "hello this is a slightly long string" + if ( + some_long_value_name_foo_bar_baz + if nesting_test_expressions + else some_fallback_value_foo_bar_baz + ) + else "this one is a little shorter" +) + +generator_expression = ( + ( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz + ) + for some_boolean_variable in some_iterable +) + + +def limit_offset_sql(self, low_mark, high_mark): + """Return LIMIT/OFFSET SQL clause.""" + limit, offset = self._get_limit_offset_params(low_mark, high_mark) + return " ".join( + sql + for sql in ( + "LIMIT %d" % limit if limit else None, + ("OFFSET %d" % offset) if offset else None, + ) + if sql + ) + + +def something(): + clone._iterable_class = ( + NamedValuesListIterable + if named + else FlatValuesListIterable if flat else ValuesListIterable + ) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring.py similarity index 97% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring.py index e1725f1f4fbfe..c3e6b9fca18a7 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring.py @@ -219,3 +219,10 @@ def stable_quote_normalization_with_immediate_inner_single_quote(self): ''' + + +def foo(): + """ + Docstring with a backslash followed by a space\ + and then another line + """ diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring.py.expect similarity index 97% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring.py.expect index a8f12a5b51702..2259a0cf01a0a 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring.py.expect @@ -217,3 +217,10 @@ def stable_quote_normalization_with_immediate_inner_single_quote(self): """ + + +def foo(): + """ + Docstring with a backslash followed by a space\ + and then another line + """ diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_no_extra_empty_line_before_eof.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_extra_empty_line_before_eof.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_no_extra_empty_line_before_eof.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_extra_empty_line_before_eof.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_no_extra_empty_line_before_eof.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_extra_empty_line_before_eof.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_no_extra_empty_line_before_eof.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_extra_empty_line_before_eof.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_no_string_normalization.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_string_normalization.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_no_string_normalization.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_string_normalization.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_no_string_normalization.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_string_normalization.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_no_string_normalization.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_string_normalization.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_preview.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_preview.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_preview.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_preview.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_preview.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_preview.py.expect similarity index 98% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_preview.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_preview.py.expect index dc453dcc76e96..859c295511617 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_preview.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_preview.py.expect @@ -3,7 +3,8 @@ def docstring_almost_at_line_limit(): def docstring_almost_at_line_limit_with_prefix(): - f"""long docstring................................................................""" + f"""long docstring................................................................ + """ def mulitline_docstring_almost_at_line_limit(): diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/empty_lines.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/empty_lines.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/empty_lines.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/empty_lines.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/empty_lines.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/empty_lines.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/empty_lines.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/empty_lines.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/expression.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/expression.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/expression.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/expression.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/expression.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/expression.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/expression.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/expression.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/f_docstring.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/f_docstring.py new file mode 100644 index 0000000000000..88dab4840f3e4 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/f_docstring.py @@ -0,0 +1,8 @@ +def foo(e): + f""" {'.'.join(e)}""" + +def bar(e): + f"{'.'.join(e)}" + +def baz(e): + F""" {'.'.join(e)}""" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/f_docstring.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/f_docstring.py.expect new file mode 100644 index 0000000000000..7081a229ed117 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/f_docstring.py.expect @@ -0,0 +1,10 @@ +def foo(e): + f""" {'.'.join(e)}""" + + +def bar(e): + f"{'.'.join(e)}" + + +def baz(e): + f""" {'.'.join(e)}""" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff2.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff2.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff2.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff2.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff2.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff2.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff2.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff2.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff3.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff3.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff3.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff3.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff3.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff3.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff3.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff3.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff4.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff4.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff4.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff4.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff4.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff4.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff4.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff4.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff5.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff5.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff5.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff5.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff5.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff5.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff5.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff5.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtpass_imports.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtpass_imports.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtpass_imports.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtpass_imports.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtpass_imports.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtpass_imports.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtpass_imports.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtpass_imports.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip2.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip2.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip2.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip2.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip2.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip2.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip2.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip2.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip3.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip3.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip3.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip3.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip3.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip3.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip3.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip3.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip4.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip4.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip4.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip4.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip4.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip4.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip4.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip4.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip5.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip5.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip5.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip5.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip5.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip5.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip5.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip5.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip6.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip6.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip6.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip6.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip6.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip6.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip6.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip6.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip7.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip7.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip7.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip7.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip7.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip7.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip7.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip7.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip8.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip8.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip8.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip8.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip8.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip8.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip8.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip8.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fstring.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fstring.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fstring.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fstring.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fstring.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/fstring.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fstring.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/fstring.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.py new file mode 100644 index 0000000000000..16915fc220c90 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.py @@ -0,0 +1,143 @@ +# normal, short, function definition +def foo(a, b) -> tuple[int, float]: ... + + +# normal, short, function definition w/o return type +def foo(a, b): ... + + +# no splitting +def foo(a: A, b: B) -> list[p, q]: + pass + + +# magic trailing comma in param list +def foo(a, b,): ... + + +# magic trailing comma in nested params in param list +def foo(a, b: tuple[int, float,]): ... + + +# magic trailing comma in return type, no params +def a() -> tuple[ + a, + b, +]: ... + + +# magic trailing comma in return type, params +def foo(a: A, b: B) -> list[ + p, + q, +]: + pass + + +# magic trailing comma in param list and in return type +def foo( + a: a, + b: b, +) -> list[ + a, + a, +]: + pass + + +# long function definition, param list is longer +def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa( + bbbbbbbbbbbbbbbbbb, +) -> cccccccccccccccccccccccccccccc: ... + + +# long function definition, return type is longer +# this should maybe split on rhs? +def aaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbb) -> list[ + Ccccccccccccccccccccccccccccccccccccccccccccccccccc, Dddddd +]: ... + + +# long return type, no param list +def foo() -> list[ + Loooooooooooooooooooooooooooooooooooong, + Loooooooooooooooooooong, + Looooooooooooong, +]: ... + + +# long function name, no param list, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong(): + pass + + +# long function name, no param list +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong() -> ( + list[int, float] +): ... + + +# long function name, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong( + a, b +): ... + + +# unskippable type hint (??) +def foo(a) -> list[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]: # type: ignore + pass + + +def foo(a) -> list[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +]: # abpedeifnore + pass + +def foo(a, b: list[Bad],): ... # type: ignore + +# don't lose any comments (no magic) +def foo( # 1 + a, # 2 + b) -> list[ # 3 + a, # 4 + b]: # 5 + ... # 6 + + +# don't lose any comments (param list magic) +def foo( # 1 + a, # 2 + b,) -> list[ # 3 + a, # 4 + b]: # 5 + ... # 6 + + +# don't lose any comments (return type magic) +def foo( # 1 + a, # 2 + b) -> list[ # 3 + a, # 4 + b,]: # 5 + ... # 6 + + +# don't lose any comments (both magic) +def foo( # 1 + a, # 2 + b,) -> list[ # 3 + a, # 4 + b,]: # 5 + ... # 6 + +# real life example +def SimplePyFn( + context: hl.GeneratorContext, + buffer_input: Buffer[UInt8, 2], + func_input: Buffer[Int32, 2], + float_arg: Scalar[Float32], + offset: int = 0, +) -> tuple[ + Buffer[UInt8, 2], + Buffer[UInt8, 2], +]: ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.py.expect new file mode 100644 index 0000000000000..bb12b80672b06 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.py.expect @@ -0,0 +1,156 @@ +# normal, short, function definition +def foo(a, b) -> tuple[int, float]: ... + + +# normal, short, function definition w/o return type +def foo(a, b): ... + + +# no splitting +def foo(a: A, b: B) -> list[p, q]: + pass + + +# magic trailing comma in param list +def foo( + a, + b, +): ... + + +# magic trailing comma in nested params in param list +def foo( + a, + b: tuple[ + int, + float, + ], +): ... + + +# magic trailing comma in return type, no params +def a() -> tuple[ + a, + b, +]: ... + + +# magic trailing comma in return type, params +def foo(a: A, b: B) -> list[ + p, + q, +]: + pass + + +# magic trailing comma in param list and in return type +def foo( + a: a, + b: b, +) -> list[ + a, + a, +]: + pass + + +# long function definition, param list is longer +def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa( + bbbbbbbbbbbbbbbbbb, +) -> cccccccccccccccccccccccccccccc: ... + + +# long function definition, return type is longer +# this should maybe split on rhs? +def aaaaaaaaaaaaaaaaa( + bbbbbbbbbbbbbbbbbb, +) -> list[Ccccccccccccccccccccccccccccccccccccccccccccccccccc, Dddddd]: ... + + +# long return type, no param list +def foo() -> list[ + Loooooooooooooooooooooooooooooooooooong, + Loooooooooooooooooooong, + Looooooooooooong, +]: ... + + +# long function name, no param list, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong(): + pass + + +# long function name, no param list +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong() -> ( + list[int, float] +): ... + + +# long function name, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong( + a, b +): ... + + +# unskippable type hint (??) +def foo(a) -> list[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]: # type: ignore + pass + + +def foo( + a, +) -> list[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +]: # abpedeifnore + pass + + +def foo( + a, + b: list[Bad], +): ... # type: ignore + + +# don't lose any comments (no magic) +def foo(a, b) -> list[a, b]: # 1 # 2 # 3 # 4 # 5 + ... # 6 + + +# don't lose any comments (param list magic) +def foo( # 1 + a, # 2 + b, +) -> list[a, b]: # 3 # 4 # 5 + ... # 6 + + +# don't lose any comments (return type magic) +def foo(a, b) -> list[ # 1 # 2 # 3 + a, # 4 + b, +]: # 5 + ... # 6 + + +# don't lose any comments (both magic) +def foo( # 1 + a, # 2 + b, +) -> list[ # 3 + a, # 4 + b, +]: # 5 + ... # 6 + + +# real life example +def SimplePyFn( + context: hl.GeneratorContext, + buffer_input: Buffer[UInt8, 2], + func_input: Buffer[Int32, 2], + float_arg: Scalar[Float32], + offset: int = 0, +) -> tuple[ + Buffer[UInt8, 2], + Buffer[UInt8, 2], +]: ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/function.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/function.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/function.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/function.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function2.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/function2.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function2.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/function2.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function2.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/function2.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function2.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/function2.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function_trailing_comma.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/function_trailing_comma.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function_trailing_comma.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/function_trailing_comma.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function_trailing_comma.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/function_trailing_comma.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function_trailing_comma.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/function_trailing_comma.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/ignore_pyi.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/ignore_pyi.pyi similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/ignore_pyi.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/ignore_pyi.pyi diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/ignore_pyi.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/ignore_pyi.pyi.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/ignore_pyi.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/ignore_pyi.pyi.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/import_spacing.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/import_spacing.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/import_spacing.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/import_spacing.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/import_spacing.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/import_spacing.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/import_spacing.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/import_spacing.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_basic.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_basic.py new file mode 100644 index 0000000000000..40d0f7053b9e2 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_basic.py @@ -0,0 +1,40 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass +def foo2(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass +def foo3(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass +def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass + +# Adding some unformated code covering a wide range of syntaxes. + +if True: + # Incorrectly indented prefix comments. + pass + +import typing +from typing import ( + Any , + ) +class MyClass( object): # Trailing comment with extra leading space. + #NOTE: The following indentation is incorrect: + @decor( 1 * 3 ) + def my_func( arg): + pass + +try: # Trailing comment with extra leading space. + for i in range(10): # Trailing comment with extra leading space. + while condition: + if something: + then_something( ) + elif something_else: + then_something_else( ) +except ValueError as e: + unformatted( ) +finally: + unformatted( ) + +async def test_async_unformatted( ): # Trailing comment with extra leading space. + async for i in some_iter( unformatted ): # Trailing comment with extra leading space. + await asyncio.sleep( 1 ) + async with some_context( unformatted ): + print( "unformatted" ) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_basic.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_basic.py.expect new file mode 100644 index 0000000000000..7fdfdfd0dbbae --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_basic.py.expect @@ -0,0 +1,63 @@ +# flags: --line-ranges=5-6 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass +def foo2( + parameter_1, + parameter_2, + parameter_3, + parameter_4, + parameter_5, + parameter_6, + parameter_7, +): + pass + + +def foo3( + parameter_1, + parameter_2, + parameter_3, + parameter_4, + parameter_5, + parameter_6, + parameter_7, +): + pass + + +def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass + +# Adding some unformated code covering a wide range of syntaxes. + +if True: + # Incorrectly indented prefix comments. + pass + +import typing +from typing import ( + Any , + ) +class MyClass( object): # Trailing comment with extra leading space. + #NOTE: The following indentation is incorrect: + @decor( 1 * 3 ) + def my_func( arg): + pass + +try: # Trailing comment with extra leading space. + for i in range(10): # Trailing comment with extra leading space. + while condition: + if something: + then_something( ) + elif something_else: + then_something_else( ) +except ValueError as e: + unformatted( ) +finally: + unformatted( ) + +async def test_async_unformatted( ): # Trailing comment with extra leading space. + async for i in some_iter( unformatted ): # Trailing comment with extra leading space. + await asyncio.sleep( 1 ) + async with some_context( unformatted ): + print( "unformatted" ) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_diff_edge_case.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_diff_edge_case.py new file mode 100644 index 0000000000000..17613eb8dbe18 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_diff_edge_case.py @@ -0,0 +1,12 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Reproducible example for https://github.com/psf/black/issues/4033. +# This can be fixed in the future if we use a better diffing algorithm, or make Black +# perform formatting in a single pass. + +print ( "format me" ) +print ( "format me" ) +print ( "format me" ) +print ( "format me" ) +print ( "format me" ) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_diff_edge_case.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_diff_edge_case.py.expect new file mode 100644 index 0000000000000..96106c6988b94 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_diff_edge_case.py.expect @@ -0,0 +1,13 @@ +# flags: --line-ranges=10-11 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Reproducible example for https://github.com/psf/black/issues/4033. +# This can be fixed in the future if we use a better diffing algorithm, or make Black +# perform formatting in a single pass. + +print ( "format me" ) +print("format me") +print("format me") +print("format me") +print("format me") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off.py new file mode 100644 index 0000000000000..bcb36284a844e --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off.py @@ -0,0 +1,22 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# fmt: off +import os +def myfunc( ): # Intentionally unformatted. + pass +# fmt: on + + +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc( ): # This will be reformatted. + print( {"this will be reformatted"} ) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off.py.expect new file mode 100644 index 0000000000000..03cd50db754c8 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off.py.expect @@ -0,0 +1,23 @@ +# flags: --line-ranges=7-7 --line-ranges=17-23 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# fmt: off +import os +def myfunc( ): # Intentionally unformatted. + pass +# fmt: on + + +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc(): # This will be reformatted. + print({"this will be reformatted"}) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_decorator.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_decorator.py new file mode 100644 index 0000000000000..8ae63e21716b8 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_decorator.py @@ -0,0 +1,20 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Regression test for an edge case involving decorators and fmt: off/on. +class MyClass: + + # fmt: off + @decorator ( ) + # fmt: on + def method(): + print ( "str" ) + + @decor( + a=1, + # fmt: off + b=(2, 3), + # fmt: on + ) + def func(): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_decorator.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_decorator.py.expect new file mode 100644 index 0000000000000..905336810bff8 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_decorator.py.expect @@ -0,0 +1,21 @@ +# flags: --line-ranges=12-12 --line-ranges=21-21 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Regression test for an edge case involving decorators and fmt: off/on. +class MyClass: + + # fmt: off + @decorator ( ) + # fmt: on + def method(): + print("str") + + @decor( + a=1, + # fmt: off + b=(2, 3), + # fmt: on + ) + def func(): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_overlap.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_overlap.py new file mode 100644 index 0000000000000..4d3db25824c64 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_overlap.py @@ -0,0 +1,16 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + + +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc( ): # This will be reformatted. + print( {"this will be reformatted"} ) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_overlap.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_overlap.py.expect new file mode 100644 index 0000000000000..fa7c683b3ace9 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_overlap.py.expect @@ -0,0 +1,17 @@ +# flags: --line-ranges=11-17 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + + +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc(): # This will be reformatted. + print({"this will be reformatted"}) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_imports.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_imports.py new file mode 100644 index 0000000000000..0e516f28226c3 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_imports.py @@ -0,0 +1,8 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# This test ensures no empty lines are added around import lines. +# It caused an issue before https://github.com/psf/black/pull/3610 is merged. +import os +import re +import sys diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_imports.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_imports.py.expect new file mode 100644 index 0000000000000..0e516f28226c3 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_imports.py.expect @@ -0,0 +1,8 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# This test ensures no empty lines are added around import lines. +# It caused an issue before https://github.com/psf/black/pull/3610 is merged. +import os +import re +import sys diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_indentation.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_indentation.py new file mode 100644 index 0000000000000..ee2269d06102d --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_indentation.py @@ -0,0 +1,11 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +if cond1: + print("first") + if cond2: + print("second") + else: + print("else") + +if another_cond: + print("will not be changed") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_indentation.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_indentation.py.expect new file mode 100644 index 0000000000000..e6265c1ded0c5 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_indentation.py.expect @@ -0,0 +1,12 @@ +# flags: --line-ranges=5-5 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +if cond1: + print("first") + if cond2: + print("second") + else: + print("else") + +if another_cond: + print("will not be changed") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_two_passes.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_two_passes.py new file mode 100644 index 0000000000000..c8a57fdf77aef --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_two_passes.py @@ -0,0 +1,12 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# This is a specific case for Black's two-pass formatting behavior in `format_str`. +# The second pass must respect the line ranges before the first pass. + + +def restrict_to_this_line(arg1, + arg2, + arg3): + print ( "This should not be formatted." ) + print ( "Note that in the second pass, the original line range 9-11 will cover these print lines.") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_two_passes.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_two_passes.py.expect new file mode 100644 index 0000000000000..593ef6d331807 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_two_passes.py.expect @@ -0,0 +1,11 @@ +# flags: --line-ranges=9-11 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# This is a specific case for Black's two-pass formatting behavior in `format_str`. +# The second pass must respect the line ranges before the first pass. + + +def restrict_to_this_line(arg1, arg2, arg3): + print ( "This should not be formatted." ) + print ( "Note that in the second pass, the original line range 9-11 will cover these print lines.") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_unwrapping.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_unwrapping.py new file mode 100644 index 0000000000000..c5db777884258 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_unwrapping.py @@ -0,0 +1,13 @@ +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +alist = [ + 1, 2 +] + +adict = { + "key" : "value" +} + +func_call ( + arg = value +) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_unwrapping.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_unwrapping.py.expect new file mode 100644 index 0000000000000..4d8de0a45d97e --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_unwrapping.py.expect @@ -0,0 +1,8 @@ +# flags: --line-ranges=5-5 --line-ranges=9-9 --line-ranges=13-13 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +alist = [1, 2] + +adict = {"key": "value"} + +func_call(arg=value) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/linelength6.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/linelength6.options.json new file mode 100644 index 0000000000000..d5eda5fc94062 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/linelength6.options.json @@ -0,0 +1 @@ +{"line_width": 6} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/linelength6.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/linelength6.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/linelength6.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/linelength6.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/linelength6.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/linelength6.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/linelength6.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/linelength6.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/long_strings_flag_disabled.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/long_strings_flag_disabled.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/long_strings_flag_disabled.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/long_strings_flag_disabled.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/long_strings_flag_disabled.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/long_strings_flag_disabled.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/long_strings_flag_disabled.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/long_strings_flag_disabled.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.py new file mode 100644 index 0000000000000..6868801be3e59 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.py @@ -0,0 +1,14 @@ +"""Single line module-level docstring should be followed by single newline.""" + + + + +a = 1 + + +"""I'm just a string so should be followed by 2 newlines.""" + + + + +b = 2 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.py.expect new file mode 100644 index 0000000000000..09fc6076ab5f8 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_1.py.expect @@ -0,0 +1,9 @@ +"""Single line module-level docstring should be followed by single newline.""" + +a = 1 + + +"""I'm just a string so should be followed by 2 newlines.""" + + +b = 2 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.py new file mode 100644 index 0000000000000..48be31c41c906 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.py @@ -0,0 +1,35 @@ +"""I am a very helpful module docstring. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, +sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +Ut enim ad minim veniam, +quis nostrud exercitation ullamco laboris +nisi ut aliquip ex ea commodo consequat. +Duis aute irure dolor in reprehenderit in voluptate +velit esse cillum dolore eu fugiat nulla pariatur. +Excepteur sint occaecat cupidatat non proident, +sunt in culpa qui officia deserunt mollit anim id est laborum. +""" + + + + +a = 1 + + +"""Look at me I'm a docstring... + +............................................................ +............................................................ +............................................................ +............................................................ +............................................................ +............................................................ +............................................................ +........................................................NOT! +""" + + + + +b = 2 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.py.expect new file mode 100644 index 0000000000000..6c07d2d16978e --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.py.expect @@ -0,0 +1,30 @@ +"""I am a very helpful module docstring. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, +sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +Ut enim ad minim veniam, +quis nostrud exercitation ullamco laboris +nisi ut aliquip ex ea commodo consequat. +Duis aute irure dolor in reprehenderit in voluptate +velit esse cillum dolore eu fugiat nulla pariatur. +Excepteur sint occaecat cupidatat non proident, +sunt in culpa qui officia deserunt mollit anim id est laborum. +""" + +a = 1 + + +"""Look at me I'm a docstring... + +............................................................ +............................................................ +............................................................ +............................................................ +............................................................ +............................................................ +............................................................ +........................................................NOT! +""" + + +b = 2 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.py new file mode 100644 index 0000000000000..f785054cefcb1 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.py @@ -0,0 +1,2 @@ +"""Single line module-level docstring should be followed by single newline.""" +a = 1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.py.expect new file mode 100644 index 0000000000000..98e7364384c7a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_3.py.expect @@ -0,0 +1,3 @@ +"""Single line module-level docstring should be followed by single newline.""" + +a = 1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.py new file mode 100644 index 0000000000000..98e7364384c7a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.py @@ -0,0 +1,3 @@ +"""Single line module-level docstring should be followed by single newline.""" + +a = 1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.py.expect new file mode 100644 index 0000000000000..98e7364384c7a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_4.py.expect @@ -0,0 +1,3 @@ +"""Single line module-level docstring should be followed by single newline.""" + +a = 1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.py new file mode 100644 index 0000000000000..5a10eeb881098 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.py @@ -0,0 +1,3 @@ +"""Two blank lines between module docstring and a class.""" +class MyClass: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.py.expect new file mode 100644 index 0000000000000..57611855321c6 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_class.py.expect @@ -0,0 +1,5 @@ +"""Two blank lines between module docstring and a class.""" + + +class MyClass: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.py new file mode 100644 index 0000000000000..5d8a52a85b066 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.py @@ -0,0 +1,3 @@ +"""Two blank lines between module docstring and a function def.""" +def function(): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.py.expect new file mode 100644 index 0000000000000..73ac8469ce827 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_followed_by_function.py.expect @@ -0,0 +1,5 @@ +"""Two blank lines between module docstring and a function def.""" + + +def function(): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/multiline_consecutive_open_parentheses_ignore.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/multiline_consecutive_open_parentheses_ignore.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/multiline_consecutive_open_parentheses_ignore.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/multiline_consecutive_open_parentheses_ignore.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/multiline_consecutive_open_parentheses_ignore.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/multiline_consecutive_open_parentheses_ignore.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/multiline_consecutive_open_parentheses_ignore.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/multiline_consecutive_open_parentheses_ignore.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.pyi b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.pyi new file mode 100644 index 0000000000000..2cb19a8ba0dd6 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.pyi @@ -0,0 +1,18 @@ +import sys + +class Outer: + class InnerStub: ... + outer_attr_after_inner_stub: int + class Inner: + inner_attr: int + outer_attr: int + +if sys.version_info > (3, 7): + if sys.platform == "win32": + assignment = 1 + def function_definition(self): ... + def f1(self) -> str: ... + if sys.platform != "win32": + def function_definition(self): ... + assignment = 1 + def f2(self) -> str: ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.pyi.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.pyi.expect new file mode 100644 index 0000000000000..da431eb8493f1 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.pyi.expect @@ -0,0 +1,22 @@ +import sys + +class Outer: + class InnerStub: ... + outer_attr_after_inner_stub: int + + class Inner: + inner_attr: int + + outer_attr: int + +if sys.version_info > (3, 7): + if sys.platform == "win32": + assignment = 1 + def function_definition(self): ... + + def f1(self) -> str: ... + if sys.platform != "win32": + def function_definition(self): ... + assignment = 1 + + def f2(self) -> str: ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals.py similarity index 91% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals.py index 6da4ba68d62d9..0aa2aef4eb6ca 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3.6 - x = 123456789 x = 123456 x = .1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals.py.expect similarity index 91% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals.py.expect index e263924b4e783..6514de6cb99d1 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals.py.expect @@ -1,5 +1,3 @@ -#!/usr/bin/env python3.6 - x = 123456789 x = 123456 x = 0.1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals_skip_underscores.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals_skip_underscores.py similarity index 79% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals_skip_underscores.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals_skip_underscores.py index d77116a8327e0..9e8f89736c077 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals_skip_underscores.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals_skip_underscores.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3.6 - x = 123456789 x = 1_2_3_4_5_6_7 x = 1E+1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals_skip_underscores.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals_skip_underscores.py.expect similarity index 79% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals_skip_underscores.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals_skip_underscores.py.expect index a81ada11e57b0..e57b5f0944d75 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_36/numeric_literals_skip_underscores.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/numeric_literals_skip_underscores.py.expect @@ -1,5 +1,3 @@ -#!/usr/bin/env python3.6 - x = 123456789 x = 1_2_3_4_5_6_7 x = 1e1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/one_element_subscript.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/one_element_subscript.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/one_element_subscript.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/one_element_subscript.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/one_element_subscript.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/one_element_subscript.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/one_element_subscript.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/one_element_subscript.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/parenthesized_context_managers.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/parenthesized_context_managers.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/parenthesized_context_managers.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/parenthesized_context_managers.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/parenthesized_context_managers.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/parenthesized_context_managers.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/parenthesized_context_managers.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/parenthesized_context_managers.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_complex.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_complex.py similarity index 90% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_complex.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_complex.py index 97ee194fd39e2..60c80b9ea1df9 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_complex.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_complex.py @@ -142,3 +142,13 @@ y = 1 case []: y = 2 +# issue 3790 +match (X.type, Y): + case _: + pass +# issue 3487 +match = re.match(r"(?PLD|MD|HD)(?PAL|SS)", "HDSS") + +match (match.group("grade"), match.group("material")): + case ("MD" | "HD", "SS" as code): + print("You will get here") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_complex.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_complex.py.expect similarity index 90% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_complex.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_complex.py.expect index 97ee194fd39e2..60c80b9ea1df9 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_complex.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_complex.py.expect @@ -142,3 +142,13 @@ match x: y = 1 case []: y = 2 +# issue 3790 +match (X.type, Y): + case _: + pass +# issue 3487 +match = re.match(r"(?PLD|MD|HD)(?PAL|SS)", "HDSS") + +match (match.group("grade"), match.group("material")): + case ("MD" | "HD", "SS" as code): + print("You will get here") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_extras.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_extras.py similarity index 88% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_extras.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_extras.py index 0242d264e5b63..5afe69920eb66 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_extras.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_extras.py @@ -29,22 +29,6 @@ def func(match: case, case: match) -> case: ... -match maybe, multiple: - case perhaps, 5: - pass - case perhaps, 6,: - pass - - -match more := (than, one), indeed,: - case _, (5, 6): - pass - case [[5], (6)], [7],: - pass - case _: - pass - - match a, *b, c: case [*_]: assert "seq" == _ @@ -66,12 +50,12 @@ def func(match: case, case: match) -> case: ), ): pass - case [a as match]: pass - case case: pass + case something: + pass match match: @@ -97,10 +81,8 @@ def func(match: case, case: match) -> case: match something: case 1 as a: pass - case 2 as b, 3 as c: pass - case 4 as d, (5 as e), (6 | 7 as g), *h: pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_extras.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_extras.py.expect similarity index 88% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_extras.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_extras.py.expect index 0242d264e5b63..5afe69920eb66 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_extras.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_extras.py.expect @@ -29,22 +29,6 @@ def func(match: case, case: match) -> case: ... -match maybe, multiple: - case perhaps, 5: - pass - case perhaps, 6,: - pass - - -match more := (than, one), indeed,: - case _, (5, 6): - pass - case [[5], (6)], [7],: - pass - case _: - pass - - match a, *b, c: case [*_]: assert "seq" == _ @@ -66,12 +50,12 @@ match match( ), ): pass - case [a as match]: pass - case case: pass + case something: + pass match match: @@ -97,10 +81,8 @@ match something: match something: case 1 as a: pass - case 2 as b, 3 as c: pass - case 4 as d, (5 as e), (6 | 7 as g), *h: pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_generic.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_generic.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_generic.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_generic.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_generic.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_generic.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_generic.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_generic.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_simple.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_simple.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_simple.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_simple.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_simple.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_simple.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_simple.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_simple.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_style.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_style.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_style.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_style.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_style.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_style.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_style.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_style.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.py new file mode 100644 index 0000000000000..bd3e48417b6b5 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.py @@ -0,0 +1,83 @@ +# This has always worked +z= Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong + +# "AnnAssign"s now also work +z: Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong +z: (Short + | Short2 + | Short3 + | Short4) +z: (int) +z: ((int)) + + +z: Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong = 7 +z: (Short + | Short2 + | Short3 + | Short4) = 8 +z: (int) = 2.3 +z: ((int)) = foo() + +# In case I go for not enforcing parantheses, this might get improved at the same time +x = ( + z + == 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999, + y + == 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999, +) + +x = ( + z == (9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999), + y == (9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999), +) + +# handle formatting of "tname"s in parameter list + +# remove unnecessary paren +def foo(i: (int)) -> None: ... + + +# this is a syntax error in the type annotation according to mypy, but it's not invalid *python* code, so make sure we don't mess with it and make it so. +def foo(i: (int,)) -> None: ... + +def foo( + i: int, + x: Loooooooooooooooooooooooong + | Looooooooooooooooong + | Looooooooooooooooooooong + | Looooooong, + *, + s: str, +) -> None: + pass + + +@app.get("/path/") +async def foo( + q: str + | None = Query(None, title="Some long title", description="Some long description") +): + pass + + +def f( + max_jobs: int + | None = Option( + None, help="Maximum number of jobs to launch. And some additional text." + ), + another_option: bool = False + ): + ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.py.expect new file mode 100644 index 0000000000000..ab0a4d96772ca --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.py.expect @@ -0,0 +1,101 @@ +# This has always worked +z = ( + Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong +) + +# "AnnAssign"s now also work +z: ( + Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong +) +z: Short | Short2 | Short3 | Short4 +z: int +z: int + + +z: ( + Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong +) = 7 +z: Short | Short2 | Short3 | Short4 = 8 +z: int = 2.3 +z: int = foo() + +# In case I go for not enforcing parantheses, this might get improved at the same time +x = ( + z + == 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999, + y + == 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999, +) + +x = ( + z + == ( + 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + ), + y + == ( + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + ), +) + +# handle formatting of "tname"s in parameter list + + +# remove unnecessary paren +def foo(i: int) -> None: ... + + +# this is a syntax error in the type annotation according to mypy, but it's not invalid *python* code, so make sure we don't mess with it and make it so. +def foo(i: (int,)) -> None: ... + + +def foo( + i: int, + x: ( + Loooooooooooooooooooooooong + | Looooooooooooooooong + | Looooooooooooooooooooong + | Looooooong + ), + *, + s: str, +) -> None: + pass + + +@app.get("/path/") +async def foo( + q: str | None = Query( + None, title="Some long title", description="Some long description" + ) +): + pass + + +def f( + max_jobs: int | None = Option( + None, help="Maximum number of jobs to launch. And some additional text." + ), + another_option: bool = False, +): ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_570.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_570.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_570.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_570.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_570.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_570.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_570.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_570.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pep_572_py310.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py310.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pep_572_py310.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py310.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pep_572_py310.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py310.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pep_572_py310.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py310.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_39/pep_572_py39.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py39.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_39/pep_572_py39.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py39.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_39/pep_572_py39.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py39.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_39/pep_572_py39.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py39.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572_remove_parens.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_remove_parens.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572_remove_parens.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_remove_parens.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572_remove_parens.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_remove_parens.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572_remove_parens.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_remove_parens.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/pep_604.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_604.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/pep_604.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_604.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/pep_604.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_604.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/pep_604.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_604.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_646.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_646.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_646.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_646.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_646.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_646.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_646.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_646.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_654.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_654.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_654.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_654.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654_style.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_654_style.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654_style.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_654_style.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654_style.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_654_style.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_311/pep_654_style.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_654_style.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_newline.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_newline.options.json new file mode 100644 index 0000000000000..70fa4ec1b938a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_newline.options.json @@ -0,0 +1 @@ +{"line_width": 1} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/power_op_newline.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_newline.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/power_op_newline.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_newline.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/power_op_newline.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_newline.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/power_op_newline.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_newline.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/power_op_spacing.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_spacing.py similarity index 93% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/power_op_spacing.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_spacing.py index 1ae3fc2b4f979..14b29b3febf50 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/power_op_spacing.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_spacing.py @@ -29,6 +29,13 @@ def function_dont_replace_spaces(): p = {(k, k**2): v**2 for k, v in pairs} q = [10**i for i in range(6)] r = x**y +s = 1 ** 1 +t = ( + 1 + ** 1 + **1 + ** 1 +) a = 5.0**~4.0 b = 5.0 ** f() @@ -47,6 +54,13 @@ def function_dont_replace_spaces(): o = settings(max_examples=10**6.0) p = {(k, k**2): v**2.0 for k, v in pairs} q = [10.5**i for i in range(6)] +s = 1.0 ** 1.0 +t = ( + 1.0 + ** 1.0 + **1.0 + ** 1.0 +) # WE SHOULD DEFINITELY NOT EAT THESE COMMENTS (https://github.com/psf/black/issues/2873) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/power_op_spacing.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_spacing.py.expect similarity index 96% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/power_op_spacing.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_spacing.py.expect index ffc2be7e78f4d..ca00fba8b3c80 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/power_op_spacing.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_spacing.py.expect @@ -29,6 +29,8 @@ o = settings(max_examples=10**6) p = {(k, k**2): v**2 for k, v in pairs} q = [10**i for i in range(6)] r = x**y +s = 1**1 +t = 1**1**1**1 a = 5.0**~4.0 b = 5.0 ** f() @@ -47,6 +49,8 @@ n = count <= 10**5.0 o = settings(max_examples=10**6.0) p = {(k, k**2): v**2.0 for k, v in pairs} q = [10.5**i for i in range(6)] +s = 1.0**1.0 +t = 1.0**1.0**1.0**1.0 # WE SHOULD DEFINITELY NOT EAT THESE COMMENTS (https://github.com/psf/black/issues/2873) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/prefer_rhs_split_reformatted.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/prefer_rhs_split_reformatted.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/prefer_rhs_split_reformatted.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/prefer_rhs_split_reformatted.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/prefer_rhs_split_reformatted.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/prefer_rhs_split_reformatted.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/prefer_rhs_split_reformatted.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/prefer_rhs_split_reformatted.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.py new file mode 100644 index 0000000000000..7cf2fc1b8c18d --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.py @@ -0,0 +1,51 @@ +def foo(): + """ + Docstring + """ + + # Here we go + if x: + + # This is also now fine + a = 123 + + else: + # But not necessary + a = 123 + + if y: + + while True: + + """ + Long comment here + """ + a = 123 + + if z: + + for _ in range(100): + a = 123 + else: + + try: + + # this should be ok + a = 123 + except: + + """also this""" + a = 123 + + +def bar(): + + if x: + a = 123 + + +def baz(): + + # OK + if x: + a = 123 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.py.expect new file mode 100644 index 0000000000000..570a63b1d3f3c --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.py.expect @@ -0,0 +1,51 @@ +def foo(): + """ + Docstring + """ + + # Here we go + if x: + + # This is also now fine + a = 123 + + else: + # But not necessary + a = 123 + + if y: + + while True: + + """ + Long comment here + """ + a = 123 + + if z: + + for _ in range(100): + a = 123 + else: + + try: + + # this should be ok + a = 123 + except: + + """also this""" + a = 123 + + +def bar(): + + if x: + a = 123 + + +def baz(): + + # OK + if x: + a = 123 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.py new file mode 100644 index 0000000000000..88767abb88cc6 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.py @@ -0,0 +1,11 @@ +async def func() -> (int): + return 0 + + +@decorated +async def func() -> (int): + return 0 + + +async for (item) in async_iter: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.py.expect new file mode 100644 index 0000000000000..13423345b6386 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_async_stmts.py.expect @@ -0,0 +1,11 @@ +async def func() -> int: + return 0 + + +@decorated +async def func() -> int: + return 0 + + +async for item in async_iter: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.py new file mode 100644 index 0000000000000..32ef2770cf719 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.py @@ -0,0 +1,39 @@ +# long variable name +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 0 +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 1 # with a comment +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = [ + 1, 2, 3 +] +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function() +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + arg1, arg2, arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +# long function name +normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying() +normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + arg1, arg2, arg3 +) +normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +# long arguments +normal_name = normal_function_name( + "but with super long string arguments that on their own exceed the line limit so there's no way it can ever fit", + "eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs", + this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it=0, +) +string_variable_name = ( + "a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do" # noqa +) +for key in """ + hostname + port + username +""".split(): + if key in self.connect_kwargs: + raise ValueError(err.format(key)) +concatenated_strings = "some strings that are " "concatenated implicitly, so if you put them on separate " "lines it will fit" +del concatenated_strings, string_variable_name, normal_function_name, normal_name, need_more_to_make_the_line_long_enough diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.py.expect new file mode 100644 index 0000000000000..27327be5f860f --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.py.expect @@ -0,0 +1,63 @@ +# long variable name +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( + 0 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( + 1 # with a comment +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = [ + 1, + 2, + 3, +] +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( + function() +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + arg1, arg2, arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +# long function name +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying() +) +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + arg1, arg2, arg3 + ) +) +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 + ) +) +# long arguments +normal_name = normal_function_name( + "but with super long string arguments that on their own exceed the line limit so" + " there's no way it can ever fit", + "eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs" + " with spam and eggs and spam with eggs", + this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it=0, +) +string_variable_name = "a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do" # noqa +for key in """ + hostname + port + username +""".split(): + if key in self.connect_kwargs: + raise ValueError(err.format(key)) +concatenated_strings = ( + "some strings that are " + "concatenated implicitly, so if you put them on separate " + "lines it will fit" +) +del ( + concatenated_strings, + string_variable_name, + normal_function_name, + normal_name, + need_more_to_make_the_line_long_enough, +) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.py new file mode 100644 index 0000000000000..14fe9b2f8bad8 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.py @@ -0,0 +1,144 @@ +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + Path, + # String, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) + + +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + no_comma_here_yet + # and some comments, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent # NOT DRY +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent as component # DRY +) + + +result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +result = ( + 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +) + +result = ( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa +) + +result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa + + +def func(): + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0789, + a[-1], # type: ignore + ) + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0789, + a[-1] # type: ignore + ) + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + a[-1] # type: ignore + ) + + # The type: ignore exception only applies to line length, not + # other types of formatting. + c = call( + "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", # type: ignore + "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa" + ) + + +class C: + @pytest.mark.parametrize( + ("post_data", "message"), + [ + # metadata_version errors. + ( + {}, + "None is an invalid value for Metadata-Version. Error: This field is" + " required. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ( + {"metadata_version": "-1"}, + "'-1' is an invalid value for Metadata-Version. Error: Unknown Metadata" + " Version see" + " https://packaging.python.org/specifications/core-metadata" + ), + # name errors. + ( + {"metadata_version": "1.2"}, + "'' is an invalid value for Name. Error: This field is required. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ( + {"metadata_version": "1.2", "name": "foo-"}, + "'foo-' is an invalid value for Name. Error: Must start and end with a" + " letter or numeral and contain only ascii numeric and '.', '_' and" + " '-'. see https://packaging.python.org/specifications/core-metadata" + ), + # version errors. + ( + {"metadata_version": "1.2", "name": "example"}, + "'' is an invalid value for Version. Error: This field is required. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ( + {"metadata_version": "1.2", "name": "example", "version": "dog"}, + "'dog' is an invalid value for Version. Error: Must start and end with" + " a letter or numeral and contain only ascii numeric and '.', '_' and" + " '-'. see https://packaging.python.org/specifications/core-metadata" + ) + ] + ) + def test_fails_invalid_post_data( + self, pyramid_config, db_request, post_data, message + ): + ... + +square = Square(4) # type: Optional[Square] + +# Regression test for https://github.com/psf/black/issues/3756. +[ + ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), +] +[ + ( # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), +] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.py.expect new file mode 100644 index 0000000000000..9e583ab571966 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.py.expect @@ -0,0 +1,161 @@ +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + Path, + # String, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) + + +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + no_comma_here_yet, + # and some comments, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent, # NOT DRY +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent as component, # DRY +) + + +result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +result = ( # aaa + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + +result = ( # aaa + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + + +def func(): + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0789, + a[-1], # type: ignore + ) + c = call(0.0123, 0.0456, 0.0789, 0.0123, 0.0789, a[-1]) # type: ignore + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + a[-1], # type: ignore + ) + + # The type: ignore exception only applies to line length, not + # other types of formatting. + c = call( + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", # type: ignore + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + ) + + +class C: + @pytest.mark.parametrize( + ("post_data", "message"), + [ + # metadata_version errors. + ( + {}, + ( + "None is an invalid value for Metadata-Version. Error: This field" + " is required. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ), + ( + {"metadata_version": "-1"}, + ( + "'-1' is an invalid value for Metadata-Version. Error: Unknown" + " Metadata Version see" + " https://packaging.python.org/specifications/core-metadata" + ), + ), + # name errors. + ( + {"metadata_version": "1.2"}, + ( + "'' is an invalid value for Name. Error: This field is required." + " see https://packaging.python.org/specifications/core-metadata" + ), + ), + ( + {"metadata_version": "1.2", "name": "foo-"}, + ( + "'foo-' is an invalid value for Name. Error: Must start and end" + " with a letter or numeral and contain only ascii numeric and '.'," + " '_' and '-'. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ), + # version errors. + ( + {"metadata_version": "1.2", "name": "example"}, + ( + "'' is an invalid value for Version. Error: This field is required." + " see https://packaging.python.org/specifications/core-metadata" + ), + ), + ( + {"metadata_version": "1.2", "name": "example", "version": "dog"}, + ( + "'dog' is an invalid value for Version. Error: Must start and end" + " with a letter or numeral and contain only ascii numeric and '.'," + " '_' and '-'. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ), + ], + ) + def test_fails_invalid_post_data( + self, pyramid_config, db_request, post_data, message + ): ... + + +square = Square(4) # type: Optional[Square] + +# Regression test for https://github.com/psf/black/issues/3756. +[ + ( # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ), +] +[ + ( # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), +] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.py new file mode 100644 index 0000000000000..811be47176279 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.py @@ -0,0 +1,31 @@ +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass + + +with \ + make_context_manager1() as cm1, \ + make_context_manager2(), \ + make_context_manager3() as cm3, \ + make_context_manager4() \ +: + pass + + +with \ + new_new_new1() as cm1, \ + new_new_new2() \ +: + pass + + +with mock.patch.object( + self.my_runner, "first_method", autospec=True +) as mock_run_adb, mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" +): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.py.expect new file mode 100644 index 0000000000000..5c0cdde0d29a5 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_38.py.expect @@ -0,0 +1,18 @@ +with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass + + +with make_context_manager1() as cm1, make_context_manager2(), make_context_manager3() as cm3, make_context_manager4(): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass + + +with mock.patch.object( + self.my_runner, "first_method", autospec=True +) as mock_run_adb, mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" +): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.py new file mode 100644 index 0000000000000..f0ae0053630a2 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.py @@ -0,0 +1,84 @@ +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass + + +# Leading comment +with \ + make_context_manager1() as cm1, \ + make_context_manager2(), \ + make_context_manager3() as cm3, \ + make_context_manager4() \ +: + pass + + +with \ + new_new_new1() as cm1, \ + new_new_new2() \ +: + pass + + +with ( + new_new_new1() as cm1, + new_new_new2() +): + pass + + +# Leading comment. +with ( + # First comment. + new_new_new1() as cm1, + # Second comment. + new_new_new2() + # Last comment. +): + pass + + +with \ + this_is_a_very_long_call(looong_arg1=looong_value1, looong_arg2=looong_value2) as cm1, \ + this_is_a_very_long_call(looong_arg1=looong_value1, looong_arg2=looong_value2, looong_arg3=looong_value3, looong_arg4=looong_value4) as cm2 \ +: + pass + + +with mock.patch.object( + self.my_runner, "first_method", autospec=True +) as mock_run_adb, mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" +): + pass + + +with xxxxxxxx.some_kind_of_method( + some_argument=[ + "first", + "second", + "third", + ] +).another_method() as cmd: + pass + + +async def func(): + async with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ + : + pass + + async with some_function( + argument1, argument2, argument3="some_value" + ) as some_cm, some_other_function( + argument1, argument2, argument3="some_value" + ): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.py.expect new file mode 100644 index 0000000000000..1b8e86593390b --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.py.expect @@ -0,0 +1,85 @@ +with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, +): + pass + + +# Leading comment +with ( + make_context_manager1() as cm1, + make_context_manager2(), + make_context_manager3() as cm3, + make_context_manager4(), +): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass + + +# Leading comment. +with ( + # First comment. + new_new_new1() as cm1, + # Second comment. + new_new_new2(), + # Last comment. +): + pass + + +with ( + this_is_a_very_long_call( + looong_arg1=looong_value1, looong_arg2=looong_value2 + ) as cm1, + this_is_a_very_long_call( + looong_arg1=looong_value1, + looong_arg2=looong_value2, + looong_arg3=looong_value3, + looong_arg4=looong_value4, + ) as cm2, +): + pass + + +with ( + mock.patch.object(self.my_runner, "first_method", autospec=True) as mock_run_adb, + mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" + ), +): + pass + + +with xxxxxxxx.some_kind_of_method( + some_argument=[ + "first", + "second", + "third", + ] +).another_method() as cmd: + pass + + +async def func(): + async with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, + ): + pass + + async with ( + some_function(argument1, argument2, argument3="some_value") as some_cm, + some_other_function(argument1, argument2, argument3="some_value"), + ): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.py new file mode 100644 index 0000000000000..493ad2110867c --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.py @@ -0,0 +1,15 @@ +# This file uses pattern matching introduced in Python 3.10. + + +match http_code: + case 404: + print("Not found") + + +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.py.expect new file mode 100644 index 0000000000000..4c35978000410 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.py.expect @@ -0,0 +1,15 @@ +# This file uses pattern matching introduced in Python 3.10. + + +match http_code: + case 404: + print("Not found") + + +with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, +): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.py new file mode 100644 index 0000000000000..fb3fb65a31129 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.py @@ -0,0 +1,16 @@ +# This file uses except* clause in Python 3.11. + + +try: + some_call() +except* Error as e: + pass + + +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.py.expect new file mode 100644 index 0000000000000..b5ca9c0b1473e --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.py.expect @@ -0,0 +1,16 @@ +# This file uses except* clause in Python 3.11. + + +try: + some_call() +except* Error as e: + pass + + +with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, +): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.py new file mode 100644 index 0000000000000..f48fbe78e3709 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.py @@ -0,0 +1,24 @@ +# This file doesn't use any Python 3.9+ only grammars. + + +# Make sure parens around a single context manager don't get autodetected as +# Python 3.9+. +with (a): + pass + + +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass + + +with mock.patch.object( + self.my_runner, "first_method", autospec=True +) as mock_run_adb, mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" +): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.py.expect new file mode 100644 index 0000000000000..d43eb9f0917ca --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_38.py.expect @@ -0,0 +1,19 @@ +# This file doesn't use any Python 3.9+ only grammars. + + +# Make sure parens around a single context manager don't get autodetected as +# Python 3.9+. +with a: + pass + + +with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass + + +with mock.patch.object( + self.my_runner, "first_method", autospec=True +) as mock_run_adb, mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" +): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.py new file mode 100644 index 0000000000000..c69d3a72894b7 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.py @@ -0,0 +1,17 @@ +# This file uses parenthesized context managers introduced in Python 3.9. + + +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass + + +with ( + new_new_new1() as cm1, + new_new_new2() +): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.py.expect new file mode 100644 index 0000000000000..ff6ce999175b2 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.py.expect @@ -0,0 +1,14 @@ +# This file uses parenthesized context managers introduced in Python 3.9. + + +with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, +): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_docstring_no_string_normalization.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_docstring_no_string_normalization.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_docstring_no_string_normalization.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_preview_no_string_normalization.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_docstring_no_string_normalization.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_preview_no_string_normalization.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_docstring_no_string_normalization.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_preview_no_string_normalization.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_docstring_no_string_normalization.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_preview_no_string_normalization.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_docstring_no_string_normalization.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.py new file mode 100644 index 0000000000000..99729fed0a28d --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.py @@ -0,0 +1,48 @@ +from typing import NoReturn, Protocol, Union, overload + + +def dummy(a): ... +def other(b): ... + + +@overload +def a(arg: int) -> int: ... +@overload +def a(arg: str) -> str: ... +@overload +def a(arg: object) -> NoReturn: ... +def a(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg + +class Proto(Protocol): + def foo(self, a: int) -> int: + ... + + def bar(self, b: str) -> str: ... + def baz(self, c: bytes) -> str: + ... + + +def dummy_two(): + ... +@dummy +def dummy_three(): + ... + +def dummy_four(): + ... + +@overload +def b(arg: int) -> int: ... + +@overload +def b(arg: str) -> str: ... +@overload +def b(arg: object) -> NoReturn: ... + +def b(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.py.expect new file mode 100644 index 0000000000000..24068c5d183ee --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.py.expect @@ -0,0 +1,48 @@ +from typing import NoReturn, Protocol, Union, overload + + +def dummy(a): ... +def other(b): ... + + +@overload +def a(arg: int) -> int: ... +@overload +def a(arg: str) -> str: ... +@overload +def a(arg: object) -> NoReturn: ... +def a(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg + + +class Proto(Protocol): + def foo(self, a: int) -> int: ... + + def bar(self, b: str) -> str: ... + def baz(self, c: bytes) -> str: ... + + +def dummy_two(): ... +@dummy +def dummy_three(): ... + + +def dummy_four(): ... + + +@overload +def b(arg: int) -> int: ... + + +@overload +def b(arg: str) -> str: ... +@overload +def b(arg: object) -> NoReturn: ... + + +def b(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.py new file mode 100644 index 0000000000000..42ba8fe243b29 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.py @@ -0,0 +1,116 @@ +# Warning! This file contains form feeds (ASCII 0x0C, often represented by \f or ^L). +# These may be invisible in your editor: ensure you can see them before making changes here. + +# There's one at the start that'll get stripped + +# Comment and statement processing is different enough that we'll test variations of both +# contexts here + +# + + +# + + +# + + + +# + + + +# + + + +# + + +# + + + +# + +# + +# + + \ +# +pass + +pass + + +pass + + +pass + + + +pass + + + +pass + + + +pass + + +pass + + + +pass + +pass + +pass + + +# form feed after a dedent +def foo(): + pass + +pass + + +# form feeds are prohibited inside blocks, or on a line with nonwhitespace + def bar( a = 1 ,b : bool = False ) : + + + pass + + +class Baz: + + def __init__(self): + pass + + + def something(self): + pass + + + +# +pass +pass # +a = 1 + # + pass + a = 1 + +a = [ + +] + +# as internal whitespace of a comment is allowed but why +"form feed literal in a string is okay " + +# form feeds at the very end get removed. diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.py.expect new file mode 100644 index 0000000000000..4895f2af697cc --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.py.expect @@ -0,0 +1,101 @@ +# Warning! This file contains form feeds (ASCII 0x0C, often represented by \f or ^L). +# These may be invisible in your editor: ensure you can see them before making changes here. + +# There's one at the start that'll get stripped + +# Comment and statement processing is different enough that we'll test variations of both +# contexts here + +# + + +# + + +# + + +# + + +# + + +# + + +# + + +# + +# + +# + +# +pass + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + +pass + +pass + + +# form feed after a dedent +def foo(): + pass + + +pass + + +# form feeds are prohibited inside blocks, or on a line with nonwhitespace +def bar(a=1, b: bool = False): + pass + + +class Baz: + def __init__(self): + pass + + def something(self): + pass + + +# +pass +pass # +a = 1 +# +pass +a = 1 + +a = [] + +# as internal whitespace of a comment is allowed but why +"form feed literal in a string is okay " + +# form feeds at the very end get removed. diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.py new file mode 100644 index 0000000000000..70699c5663413 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.py @@ -0,0 +1,15 @@ +x = "\x1F" +x = "\\x1B" +x = "\\\x1B" +x = "\U0001F60E" +x = "\u0001F60E" +x = r"\u0001F60E" +x = "don't format me" +x = "\xA3" +x = "\u2717" +x = "\uFaCe" +x = "\N{ox}\N{OX}" +x = "\N{lAtIn smaLL letteR x}" +x = "\N{CYRILLIC small LETTER BYELORUSSIAN-UKRAINIAN I}" +x = b"\x1Fdon't byte" +x = rb"\x1Fdon't format" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.py.expect new file mode 100644 index 0000000000000..d12e858bf0a3f --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.py.expect @@ -0,0 +1,15 @@ +x = "\x1f" +x = "\\x1B" +x = "\\\x1b" +x = "\U0001f60e" +x = "\u0001F60E" +x = r"\u0001F60E" +x = "don't format me" +x = "\xa3" +x = "\u2717" +x = "\uface" +x = "\N{OX}\N{OX}" +x = "\N{LATIN SMALL LETTER X}" +x = "\N{CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I}" +x = b"\x1fdon't byte" +x = rb"\x1Fdon't format" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.py new file mode 100644 index 0000000000000..2560ff5c1fb2b --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.py @@ -0,0 +1,185 @@ +def foo_brackets(request): + return JsonResponse( + { + "var_1": foo, + "var_2": bar, + } + ) + +def foo_square_brackets(request): + return JsonResponse( + [ + "var_1", + "var_2", + ] + ) + +func({"a": 37, "b": 42, "c": 927, "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111}) + +func(["random_string_number_one","random_string_number_two","random_string_number_three","random_string_number_four"]) + +func( + { + # expand me + 'a':37, + 'b':42, + 'c':927 + } +) + +func( + [ + 'a', + 'b', + 'c', + ] +) + +func( + [ + 'a', + 'b', + 'c', + ], +) + +func( # a + [ # b + "c", # c + "d", # d + "e", # e + ] # f +) # g + +func( # a + { # b + "c": 1, # c + "d": 2, # d + "e": 3, # e + } # f +) # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func( + [ # preserve me but hug brackets + "c", + "d", + "e", + ] +) + +func( + [ + # preserve me but hug brackets + "c", + "d", + "e", + ] +) + +func( + [ + "c", + # preserve me but hug brackets + "d", + "e", + ] +) + +func( + [ + "c", + "d", + "e", + # preserve me but hug brackets + ] +) + +func( + [ + "c", + "d", + "e", + ] # preserve me but hug brackets +) + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func([x for x in "long line long line long line long line long line long line long line"]) +func([x for x in [x for x in "long line long line long line long line long line long line long line"]]) + +func({"short line"}) +func({"long line", "long long line", "long long long line", "long long long long line", "long long long long long line"}) +func({{"long line", "long long line", "long long long line", "long long long long line", "long long long long long line"}}) +func(("long line", "long long line", "long long long line", "long long long long line", "long long long long long line")) +func((("long line", "long long line", "long long long line", "long long long long line", "long long long long long line"))) +func([["long line", "long long line", "long long long line", "long long long long line", "long long long long long line"]]) + +# Do not hug if the argument fits on a single line. +func({"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"}) +func(("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line")) +func(["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"]) +func(**{"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit---"}) +func(*("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit----")) +array = [{"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"}] +array = [("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line")] +array = [["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"]] + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +nested_mapping = {"key": [{"a very long key 1": "with a very long value", "a very long key 2": "with a very long value"}]} +nested_array = [[["long line", "long long line", "long long long line", "long long long long line", "long long long long long line"]]] +explicit_exploding = [[["short", "line",],],] +single_item_do_not_explode = Context({ + "version": get_docs_version(), +}) + +foo(*["long long long long long line", "long long long long long line", "long long long long long line"]) + +foo(*[str(i) for i in range(100000000000000000000000000000000000000000000000000000000000)]) + +foo( + **{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": 1, + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb": 2, + "ccccccccccccccccccccccccccccccccc": 3, + **other, + } +) + +foo(**{x: y for x, y in enumerate(["long long long long line","long long long long line"])}) + +# Edge case when deciding whether to hug the brackets without inner content. +very_very_very_long_variable = very_very_very_long_module.VeryVeryVeryVeryLongClassName([[]]) + +for foo in ["a", "b"]: + output.extend([ + individual + for + # Foobar + container in xs_by_y[foo] + # Foobar + for individual in container["nested"] + ]) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.py.expect new file mode 100644 index 0000000000000..a4f879e6dea5d --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.py.expect @@ -0,0 +1,255 @@ +def foo_brackets(request): + return JsonResponse({ + "var_1": foo, + "var_2": bar, + }) + + +def foo_square_brackets(request): + return JsonResponse([ + "var_1", + "var_2", + ]) + + +func({ + "a": 37, + "b": 42, + "c": 927, + "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111, +}) + +func([ + "random_string_number_one", + "random_string_number_two", + "random_string_number_three", + "random_string_number_four", +]) + +func({ + # expand me + "a": 37, + "b": 42, + "c": 927, +}) + +func([ + "a", + "b", + "c", +]) + +func( + [ + "a", + "b", + "c", + ], +) + +func([ # a # b + "c", # c + "d", # d + "e", # e +]) # f # g + +func({ # a # b + "c": 1, # c + "d": 2, # d + "e": 3, # e +}) # f # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func([ # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + "c", + # preserve me but hug brackets + "d", + "e", +]) + +func([ + "c", + "d", + "e", + # preserve me but hug brackets +]) + +func([ + "c", + "d", + "e", +]) # preserve me but hug brackets + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func( + [x for x in "long line long line long line long line long line long line long line"] +) +func([ + x + for x in [ + x + for x in "long line long line long line long line long line long line long line" + ] +]) + +func({"short line"}) +func({ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +}) +func({{ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +}}) +func(( + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +)) +func((( + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +))) +func([[ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +]]) + +# Do not hug if the argument fits on a single line. +func( + {"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"} +) +func( + ("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line") +) +func( + ["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"] +) +func( + **{"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit---"} +) +func( + *("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit----") +) +array = [ + {"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"} +] +array = [ + ("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line") +] +array = [ + ["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"] +] + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +nested_mapping = { + "key": [{ + "a very long key 1": "with a very long value", + "a very long key 2": "with a very long value", + }] +} +nested_array = [[[ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +]]] +explicit_exploding = [ + [ + [ + "short", + "line", + ], + ], +] +single_item_do_not_explode = Context({ + "version": get_docs_version(), +}) + +foo(*[ + "long long long long long line", + "long long long long long line", + "long long long long long line", +]) + +foo(*[ + str(i) for i in range(100000000000000000000000000000000000000000000000000000000000) +]) + +foo(**{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": 1, + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb": 2, + "ccccccccccccccccccccccccccccccccc": 3, + **other, +}) + +foo(**{ + x: y for x, y in enumerate(["long long long long line", "long long long long line"]) +}) + +# Edge case when deciding whether to hug the brackets without inner content. +very_very_very_long_variable = very_very_very_long_module.VeryVeryVeryVeryLongClassName( + [[]] +) + +for foo in ["a", "b"]: + output.extend([ + individual + for + # Foobar + container in xs_by_y[foo] + # Foobar + for individual in container["nested"] + ]) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.py new file mode 100644 index 0000000000000..67ff7b671cb45 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.py @@ -0,0 +1,36 @@ +my_dict = { + "something_something": + r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t", +} + +my_dict = { + "a key in my dict": a_very_long_variable * and_a_very_long_function_call() / 100000.0 +} + +my_dict = { + "a key in my dict": a_very_long_variable * and_a_very_long_function_call() * and_another_long_func() / 100000.0 +} + +my_dict = { + "a key in my dict": MyClass.some_attribute.first_call().second_call().third_call(some_args="some value") +} + +{ + 'xxxxxx': + xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx( + xxxxxxxxxxxxxx={ + 'x': + xxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + .xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + .xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx={ + 'x': x.xx, + 'x': x.x, + })))) + }), +} diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.py.expect new file mode 100644 index 0000000000000..e9ec664093a92 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.py.expect @@ -0,0 +1,49 @@ +my_dict = { + "something_something": ( + r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + ), +} + +my_dict = { + "a key in my dict": ( + a_very_long_variable * and_a_very_long_function_call() / 100000.0 + ) +} + +my_dict = { + "a key in my dict": ( + a_very_long_variable + * and_a_very_long_function_call() + * and_another_long_func() + / 100000.0 + ) +} + +my_dict = { + "a key in my dict": ( + MyClass.some_attribute.first_call() + .second_call() + .third_call(some_args="some value") + ) +} + +{ + "xxxxxx": xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx( + xxxxxxxxxxxxxx={ + "x": xxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx={ + "x": x.xx, + "x": x.x, + } + ) + ) + ) + ) + } + ), +} diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.py new file mode 100644 index 0000000000000..017f679115a06 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.py @@ -0,0 +1,329 @@ +x = "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +x += "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +y = ( + 'Short string' +) + +print('This is a really long string inside of a print statement with extra arguments attached at the end of it.', x, y, z) + +print("This is a really long string inside of a print statement with no extra arguments attached at the end of it.") + +D1 = {"The First": "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", "The Second": "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary."} + +D2 = {1.0: "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", 2.0: "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary."} + +D3 = {x: "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", y: "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary."} + +D4 = {"A long and ridiculous {}".format(string_key): "This is a really really really long string that has to go i,side of a dictionary. It is soooo bad.", some_func("calling", "some", "stuff"): "This is a really really really long string that has to go inside of a dictionary. It is {soooo} bad (#{x}).".format(sooo="soooo", x=2), "A %s %s" % ("formatted", "string"): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)." % ("soooo", 2)} + +D5 = { # Test for https://github.com/psf/black/issues/3261 + ("This is a really long string that can't be expected to fit in one line and is used as a nested dict's key"): {"inner": "value"}, +} + +D6 = { # Test for https://github.com/psf/black/issues/3261 + ("This is a really long string that can't be expected to fit in one line and is used as a dict's key"): ["value1", "value2"], +} + +L1 = ["The is a short string", "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a list literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", short_call("arg", {"key": "value"}), "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a list literal.", ("parens should be stripped for short string in list")] + +L2 = ["This is a really long string that can't be expected to fit in one line and is the only child of a list literal."] + +S1 = {"The is a short string", "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a set literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", short_call("arg", {"key": "value"}), "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a set literal.", ("parens should be stripped for short string in set")} + +S2 = {"This is a really long string that can't be expected to fit in one line and is the only child of a set literal."} + +T1 = ("The is a short string", "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a tuple literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", short_call("arg", {"key": "value"}), "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a tuple literal.", ("parens should be stripped for short string in list")) + +T2 = ("This is a really long string that can't be expected to fit in one line and is the only child of a tuple literal.",) + +func_with_keywords(my_arg, my_kwarg="Long keyword strings also need to be wrapped, but they will probably need to be handled a little bit differently.") + +bad_split1 = ( + 'But what should happen when code has already been formatted but in the wrong way? Like' + " with a space at the end instead of the beginning. Or what about when it is split too soon?" +) + +bad_split2 = "But what should happen when code has already " \ + "been formatted but in the wrong way? Like " \ + "with a space at the end instead of the " \ + "beginning. Or what about when it is split too " \ + "soon? In the case of a split that is too " \ + "short, black will try to honer the custom " \ + "split." + +bad_split3 = ( + "What if we have inline comments on " # First Comment + "each line of a bad split? In that " # Second Comment + "case, we should just leave it alone." # Third Comment +) + +bad_split_func1( + "But what should happen when code has already " + "been formatted but in the wrong way? Like " + "with a space at the end instead of the " + "beginning. Or what about when it is split too " + "soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split.", + xxx, yyy, zzz +) + +bad_split_func2( + xxx, yyy, zzz, + long_string_kwarg="But what should happen when code has already been formatted but in the wrong way? Like " + "with a space at the end instead of the beginning. Or what about when it is split too " + "soon?", +) + +bad_split_func3( + ( + "But what should happen when code has already " + r"been formatted but in the wrong way? Like " + "with a space at the end instead of the " + r"beginning. Or what about when it is split too " + r"soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split." + ), + xxx, + yyy, + zzz, +) + +inline_comments_func1( + "if there are inline " + "comments in the middle " + # Here is the standard alone comment. + "of the implicitly concatenated " + "string, we should handle " + "them correctly", + xxx, +) + +inline_comments_func2( + "what if the string is very very very very very very very very very very long and this part does " + "not fit into a single line? " + # Here is the standard alone comment. + "then the string should still be properly handled by merging and splitting " + "it into parts that fit in line length.", + xxx, +) + +raw_string = r"This is a long raw string. When re-formatting this string, black needs to make sure it prepends the 'r' onto the new string." + +fmt_string1 = "We also need to be sure to preserve any and all {} which may or may not be attached to the string in question.".format("method calls") + +fmt_string2 = "But what about when the string is {} but {}".format("short", "the method call is really really really really really really really really long?") + +old_fmt_string1 = "While we are on the topic of %s, we should also note that old-style formatting must also be preserved, since some %s still uses it." % ("formatting", "code") + +old_fmt_string2 = "This is a %s %s %s %s" % ("really really really really really", "old", "way to format strings!", "Use f-strings instead!") + +old_fmt_string3 = "Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s" % ("really really really really really", "old", "way to format strings!", "Use f-strings instead!") + +fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one." + +fstring_with_no_fexprs = f"Some regular string that needs to get split certainly but is NOT an fstring by any means whatsoever." + +comment_string = "Long lines with inline comments should have their comments appended to the reformatted string's enclosing right parentheses." # This comment gets thrown to the top. + +arg_comment_string = print("Long lines with inline comments which are apart of (and not the only member of) an argument list should have their comments appended to the reformatted string's enclosing left parentheses.", # This comment gets thrown to the top. + "Arg #2", "Arg #3", "Arg #4", "Arg #5") + +pragma_comment_string1 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa: E501 + +pragma_comment_string2 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa + +"""This is a really really really long triple quote string and it should not be touched.""" + +triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched.""" + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception." + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string {}.".format("formatting") + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s." % "formatting" + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s." % ("string", "formatting") + +some_function_call("With a reallly generic name and with a really really long string that is, at some point down the line, " + added + " to a variable and then added to another string.") + +some_function_call("With a reallly generic name and with a really really long string that is, at some point down the line, " + added + " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.", "and a second argument", and_a_third) + +return "A really really really really really really really really really really really really really long {} {}".format("return", "value") + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma which should NOT be there.", +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma which should NOT be there.", # comment after comma +) + +func_with_bad_comma( + ( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there." + ), +) + +func_with_bad_comma( + ( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there." + ), # comment after comma +) + +func_with_bad_parens_that_wont_fit_in_one_line( + ("short string that should have parens stripped"), + x, + y, + z +) + +func_with_bad_parens_that_wont_fit_in_one_line( + x, + y, + ("short string that should have parens stripped"), + z +) + +func_with_bad_parens( + ("short string that should have parens stripped"), + x, + y, + z, +) + +func_with_bad_parens( + x, + y, + ("short string that should have parens stripped"), + z, +) + +annotated_variable: Final = "This is a large " + STRING + " that has been " + CONCATENATED + "using the '+' operator." +annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." +annotated_variable: Literal["fakse_literal"] = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." + +backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\" +backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\\\" +backslashes = "This is a really 'long' string with \"embedded double quotes\" and 'single' quotes that also handles checking for an odd number of backslashes \\\", like this...\\\\\\" + +short_string = ( + "Hi" + " there." +) + +func_call( + short_string=( + "Hi" + " there." + ) +) + +raw_strings = r"Don't" " get" r" merged" " unless they are all raw." + +def foo(): + yield "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +x = f"This is a {{really}} long string that needs to be split without a doubt (i.e. most definitely). In short, this {string} that can't possibly be {{expected}} to fit all together on one line. In {fact} it may even take up three or more lines... like four or five... but probably just four." + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # type: ignore + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # noqa + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # pylint: disable=some-pylint-check + " of it." +) + +string_with_nameescape = ( + "........................................................................ \N{LAO KO LA}" +) + +string_with_nameescape = ( + "........................................................................... \N{LAO KO LA}" +) + +string_with_nameescape = ( + "............................................................................ \N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + "...................................................................... \\\N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + "......................................................................... \\\N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + ".......................................................................... \\\N{LAO KO LA}" +) + +string_with_escaped_nameescape = ( + "........................................................................ \\N{LAO KO LA}" +) + +string_with_escaped_nameescape = ( + "........................................................................... \\N{LAO KO LA}" +) + +msg = lambda x: f"this is a very very very long lambda value {x} that doesn't fit on a single line" + +dict_with_lambda_values = { + "join": lambda j: ( + f"{j.__class__.__name__}({some_function_call(j.left)}, " + f"{some_function_call(j.right)})" + ), +} + +# Complex string concatenations with a method call in the middle. +code = ( + (" return [\n") + + ( + ", \n".join( + " (%r, self.%s, visitor.%s)" + % (attrname, attrname, visit_name) + for attrname, visit_name in names + ) + ) + + ("\n ]\n") +) + + +# Test case of an outer string' parens enclose an inner string's parens. +call(body=("%s %s" % ((",".join(items)), suffix))) + +log.info(f'Skipping: {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]=} {desc["exposure_max"]=}') + +log.info(f"Skipping: {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']=} {desc['exposure_max']=}") + +log.info(f'Skipping: {desc["db_id"]} {foo("bar",x=123)} {"foo" != "bar"} {(x := "abc=")} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {"a" == "b" == "c" == "d"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: { longer_longer_longer_longer_longer_longer_name [ "db_id" ] [ "another_key" ] = : .3f }') + +log.info(f'''Skipping: {"a" == 'b'} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}''') + +log.info(f'''Skipping: {'a' == "b"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}''') + +log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}""") diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.py.expect new file mode 100644 index 0000000000000..4b7bdd86d2baa --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.py.expect @@ -0,0 +1,594 @@ +x = ( + "This is a really long string that can't possibly be expected to fit all together" + " on one line. In fact it may even take up three or more lines... like four or" + " five... but probably just three." +) + +x += ( + "This is a really long string that can't possibly be expected to fit all together" + " on one line. In fact it may even take up three or more lines... like four or" + " five... but probably just three." +) + +y = "Short string" + +print( + "This is a really long string inside of a print statement with extra arguments" + " attached at the end of it.", + x, + y, + z, +) + +print( + "This is a really long string inside of a print statement with no extra arguments" + " attached at the end of it." +) + +D1 = { + "The First": ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a dictionary, so formatting is more" + " difficult." + ), + "The Second": ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a" + " dictionary." + ), +} + +D2 = { + 1.0: ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a dictionary, so formatting is more" + " difficult." + ), + 2.0: ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a" + " dictionary." + ), +} + +D3 = { + x: ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a dictionary, so formatting is more" + " difficult." + ), + y: ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a" + " dictionary." + ), +} + +D4 = { + "A long and ridiculous {}".format(string_key): ( + "This is a really really really long string that has to go i,side of a" + " dictionary. It is soooo bad." + ), + some_func("calling", "some", "stuff"): ( + "This is a really really really long string that has to go inside of a" + " dictionary. It is {soooo} bad (#{x}).".format(sooo="soooo", x=2) + ), + "A %s %s" + % ("formatted", "string"): ( + "This is a really really really long string that has to go inside of a" + " dictionary. It is %s bad (#%d)." % ("soooo", 2) + ), +} + +D5 = { # Test for https://github.com/psf/black/issues/3261 + "This is a really long string that can't be expected to fit in one line and is used as a nested dict's key": { + "inner": "value" + }, +} + +D6 = { # Test for https://github.com/psf/black/issues/3261 + "This is a really long string that can't be expected to fit in one line and is used as a dict's key": [ + "value1", + "value2", + ], +} + +L1 = [ + "The is a short string", + ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a list literal, so it's expected to" + " be wrapped in parens when splitting to avoid implicit str concatenation." + ), + short_call("arg", {"key": "value"}), + ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a list" + " literal." + ), + "parens should be stripped for short string in list", +] + +L2 = [ + "This is a really long string that can't be expected to fit in one line and is the" + " only child of a list literal." +] + +S1 = { + "The is a short string", + ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a set literal, so it's expected to be" + " wrapped in parens when splitting to avoid implicit str concatenation." + ), + short_call("arg", {"key": "value"}), + ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a set" + " literal." + ), + "parens should be stripped for short string in set", +} + +S2 = { + "This is a really long string that can't be expected to fit in one line and is the" + " only child of a set literal." +} + +T1 = ( + "The is a short string", + ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a tuple literal, so it's expected to" + " be wrapped in parens when splitting to avoid implicit str concatenation." + ), + short_call("arg", {"key": "value"}), + ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a tuple" + " literal." + ), + "parens should be stripped for short string in list", +) + +T2 = ( + ( + "This is a really long string that can't be expected to fit in one line and is" + " the only child of a tuple literal." + ), +) + +func_with_keywords( + my_arg, + my_kwarg=( + "Long keyword strings also need to be wrapped, but they will probably need to" + " be handled a little bit differently." + ), +) + +bad_split1 = ( + "But what should happen when code has already been formatted but in the wrong way?" + " Like with a space at the end instead of the beginning. Or what about when it is" + " split too soon?" +) + +bad_split2 = ( + "But what should happen when code has already " + "been formatted but in the wrong way? Like " + "with a space at the end instead of the " + "beginning. Or what about when it is split too " + "soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split." +) + +bad_split3 = ( + "What if we have inline comments on " # First Comment + "each line of a bad split? In that " # Second Comment + "case, we should just leave it alone." # Third Comment +) + +bad_split_func1( + "But what should happen when code has already " + "been formatted but in the wrong way? Like " + "with a space at the end instead of the " + "beginning. Or what about when it is split too " + "soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split.", + xxx, + yyy, + zzz, +) + +bad_split_func2( + xxx, + yyy, + zzz, + long_string_kwarg=( + "But what should happen when code has already been formatted but in the wrong" + " way? Like with a space at the end instead of the beginning. Or what about" + " when it is split too soon?" + ), +) + +bad_split_func3( + ( + "But what should happen when code has already " + r"been formatted but in the wrong way? Like " + "with a space at the end instead of the " + r"beginning. Or what about when it is split too " + r"soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split." + ), + xxx, + yyy, + zzz, +) + +inline_comments_func1( + "if there are inline comments in the middle " + # Here is the standard alone comment. + "of the implicitly concatenated string, we should handle them correctly", + xxx, +) + +inline_comments_func2( + "what if the string is very very very very very very very very very very long and" + " this part does not fit into a single line? " + # Here is the standard alone comment. + "then the string should still be properly handled by merging and splitting " + "it into parts that fit in line length.", + xxx, +) + +raw_string = ( + r"This is a long raw string. When re-formatting this string, black needs to make" + r" sure it prepends the 'r' onto the new string." +) + +fmt_string1 = ( + "We also need to be sure to preserve any and all {} which may or may not be" + " attached to the string in question.".format("method calls") +) + +fmt_string2 = "But what about when the string is {} but {}".format( + "short", + "the method call is really really really really really really really really long?", +) + +old_fmt_string1 = ( + "While we are on the topic of %s, we should also note that old-style formatting" + " must also be preserved, since some %s still uses it." % ("formatting", "code") +) + +old_fmt_string2 = "This is a %s %s %s %s" % ( + "really really really really really", + "old", + "way to format strings!", + "Use f-strings instead!", +) + +old_fmt_string3 = ( + "Whereas only the strings after the percent sign were long in the last example," + " this example uses a long initial string as well. This is another %s %s %s %s" + % ( + "really really really really really", + "old", + "way to format strings!", + "Use f-strings instead!", + ) +) + +fstring = ( + f"f-strings definitely make things more {difficult} than they need to be for" + " {black}. But boy they sure are handy. The problem is that some lines will need" + f" to have the 'f' whereas others do not. This {line}, for example, needs one." +) + +fstring_with_no_fexprs = ( + f"Some regular string that needs to get split certainly but is NOT an fstring by" + f" any means whatsoever." +) + +comment_string = ( # This comment gets thrown to the top. + "Long lines with inline comments should have their comments appended to the" + " reformatted string's enclosing right parentheses." +) + +arg_comment_string = print( + "Long lines with inline comments which are apart of (and not the only member of) an" + " argument list should have their comments appended to the reformatted string's" + " enclosing left parentheses.", # This comment gets thrown to the top. + "Arg #2", + "Arg #3", + "Arg #4", + "Arg #5", +) + +pragma_comment_string1 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa: E501 + +pragma_comment_string2 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa + +"""This is a really really really long triple quote string and it should not be touched.""" + +triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched.""" + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to" + " the AssertionError exception." +) + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to" + " the AssertionError exception, which uses dynamic string {}.".format("formatting") +) + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to" + " the AssertionError exception, which uses dynamic string %s." % "formatting" +) + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to" + " the AssertionError exception, which uses dynamic %s %s." + % ("string", "formatting") +) + +some_function_call( + "With a reallly generic name and with a really really long string that is, at some" + " point down the line, " + + added + + " to a variable and then added to another string." +) + +some_function_call( + "With a reallly generic name and with a really really long string that is, at some" + " point down the line, " + + added + + " to a variable and then added to another string. But then what happens when the" + " final string is also supppppperrrrr long?! Well then that second (realllllllly" + " long) string should be split too.", + "and a second argument", + and_a_third, +) + +return ( + "A really really really really really really really really really really really" + " really really long {} {}".format("return", "value") +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there.", +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there.", # comment after comma +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there.", +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there.", # comment after comma +) + +func_with_bad_parens_that_wont_fit_in_one_line( + "short string that should have parens stripped", x, y, z +) + +func_with_bad_parens_that_wont_fit_in_one_line( + x, y, "short string that should have parens stripped", z +) + +func_with_bad_parens( + "short string that should have parens stripped", + x, + y, + z, +) + +func_with_bad_parens( + x, + y, + "short string that should have parens stripped", + z, +) + +annotated_variable: Final = ( + "This is a large " + + STRING + + " that has been " + + CONCATENATED + + "using the '+' operator." +) +annotated_variable: Final = ( + "This is a large string that has a type annotation attached to it. A type" + " annotation should NOT stop a long string from being wrapped." +) +annotated_variable: Literal["fakse_literal"] = ( + "This is a large string that has a type annotation attached to it. A type" + " annotation should NOT stop a long string from being wrapped." +) + +backslashes = ( + "This is a really long string with \"embedded\" double quotes and 'single' quotes" + " that also handles checking for an even number of backslashes \\" +) +backslashes = ( + "This is a really long string with \"embedded\" double quotes and 'single' quotes" + " that also handles checking for an even number of backslashes \\\\" +) +backslashes = ( + "This is a really 'long' string with \"embedded double quotes\" and 'single' quotes" + ' that also handles checking for an odd number of backslashes \\", like' + " this...\\\\\\" +) + +short_string = "Hi there." + +func_call(short_string="Hi there.") + +raw_strings = r"Don't" " get" r" merged" " unless they are all raw." + + +def foo(): + yield ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. In fact it may even take up three or more lines... like" + " four or five... but probably just three." + ) + + +x = ( + "This is a {really} long string that needs to be split without a doubt (i.e." + f" most definitely). In short, this {string} that can't possibly be {{expected}} to" + f" fit all together on one line. In {fact} it may even take up three or more" + " lines... like four or five... but probably just four." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # type: ignore + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # noqa + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # pylint: disable=some-pylint-check + " of it." +) + +string_with_nameescape = ( + "........................................................................" + " \N{LAO KO LA}" +) + +string_with_nameescape = ( + "..........................................................................." + " \N{LAO KO LA}" +) + +string_with_nameescape = ( + "............................................................................" + " \N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + "......................................................................" + " \\\N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + "........................................................................." + " \\\N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + ".........................................................................." + " \\\N{LAO KO LA}" +) + +string_with_escaped_nameescape = ( + "........................................................................ \\N{LAO" + " KO LA}" +) + +string_with_escaped_nameescape = ( + "..........................................................................." + " \\N{LAO KO LA}" +) + +msg = ( + lambda x: ( + f"this is a very very very long lambda value {x} that doesn't fit on a single" + " line" + ) +) + +dict_with_lambda_values = { + "join": lambda j: ( + f"{j.__class__.__name__}({some_function_call(j.left)}, " + f"{some_function_call(j.right)})" + ), +} + +# Complex string concatenations with a method call in the middle. +code = ( + " return [\n" + + ", \n".join( + " (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name) + for attrname, visit_name in names + ) + + "\n ]\n" +) + + +# Test case of an outer string' parens enclose an inner string's parens. +call(body="%s %s" % (",".join(items), suffix)) + +log.info( + "Skipping:" + f' {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]=} {desc["exposure_max"]=}' +) + +log.info( + "Skipping:" + f" {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']=} {desc['exposure_max']=}" +) + +log.info( + "Skipping:" + f" {desc['db_id']} {foo('bar',x=123)} {'foo' != 'bar'} {(x := 'abc=')} {pos_share=} {desc['status']} {desc['exposure_max']}" +) + +log.info( + "Skipping:" + f' {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + "Skipping:" + f' {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + "Skipping:" + f' {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + "Skipping:" + f" {'a' == 'b' == 'c' == 'd'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}" +) + +log.info( + "Skipping:" + f' {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + "Skipping:" + f' { longer_longer_longer_longer_longer_longer_name [ "db_id" ] [ "another_key" ] = : .3f }' +) + +log.info( + f"""Skipping: {"a" == 'b'} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}""" +) + +log.info( + f"""Skipping: {'a' == "b"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}""" +) + +log.info( + f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}""" +) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.py new file mode 100644 index 0000000000000..e807dc2035db7 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.py @@ -0,0 +1,6 @@ +# The following strings do not have not-so-many chars, but are long enough +# when these are rendered in a monospace font (if the renderer respects +# Unicode East Asian Width properties). +hangul = '코드포인트 수는 적으나 실제 터미널이나 에디터에서 렌더링될 땐 너무 길어서 줄바꿈이 필요한 문자열' +hanzi = '中文測試:代碼點數量少,但在真正的終端模擬器或編輯器中呈現時太長,因此需要換行的字符串。' +japanese = 'コードポイントの数は少ないが、実際の端末エミュレータやエディタでレンダリングされる時は長すぎる為、改行が要る文字列' diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.py.expect new file mode 100644 index 0000000000000..c5c05b31fa9d9 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.py.expect @@ -0,0 +1,16 @@ +# The following strings do not have not-so-many chars, but are long enough +# when these are rendered in a monospace font (if the renderer respects +# Unicode East Asian Width properties). +hangul = ( + "코드포인트 수는 적으나 실제 터미널이나 에디터에서 렌더링될 땐 너무 길어서 줄바꿈이" + " 필요한 문자열" +) +hanzi = ( + "中文測試:代碼點數量少,但在真正的終端模擬器或編輯器中呈現時太長," + "因此需要換行的字符串。" +) +japanese = ( + "コードポイントの数は少ないが、" + "実際の端末エミュレータやエディタでレンダリングされる時は長すぎる為、" + "改行が要る文字列" +) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.py new file mode 100644 index 0000000000000..c747ad388607b --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.py @@ -0,0 +1,37 @@ +some_variable = "This string is long but not so long that it needs to be split just yet" +some_variable = 'This string is long but not so long that it needs to be split just yet' +some_variable = "This string is long, just long enough that it needs to be split, u get?" +some_variable = 'This string is long, just long enough that it needs to be split, u get?' +some_variable = "This string is long, just long enough that it needs to be split, u get? So we stay" +some_variable = 'This string is long, just long enough that it needs to be split, u get? So we stay' +some_variable = "This string is long, just long enough that it needs to be split, u get? So we split" +some_variable = 'This string is long, just long enough that it needs to be split, u get? So we split' +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at alll".format("ha") +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at allll".format("ha") +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at alllllllllll".format("ha") +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at allllllllllll".format("ha") +some_variable = "This is a long string that will end with a method that is not calleddd".format +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take place.............", + xyz, + "Some really long string that needs to get split eventually but I'm running out of things to say" + some_string_inside_a_variable +) +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take place.............." +) +return "Hi there. This is areally really reallllly long string that needs to be split!!!" +ternary_expression = ( + "Short String" + if some_condition + else "This is a really long string that will eventually need to be split right here." +) +return f'{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaa' +return f'{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaaa' +assert str(result) == "This long string should be split at some point right close to or around hereeeeeee" +assert str(result) < "This long string should be split at some point right close to or around hereeeeee" +assert "A format string: %s" % "This long string should be split at some point right close to or around hereeeeeee" != result +msg += "This long string should be wrapped in parens at some point right around hereeeee" +msg += "This long string should be split at some point right close to or around hereeeeeeee" +msg += "This long string should not be split at any point ever since it is just righttt" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.py.expect new file mode 100644 index 0000000000000..12ffc671d2a37 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.py.expect @@ -0,0 +1,98 @@ +some_variable = "This string is long but not so long that it needs to be split just yet" +some_variable = "This string is long but not so long that it needs to be split just yet" +some_variable = ( + "This string is long, just long enough that it needs to be split, u get?" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get?" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we stay" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we stay" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we" + " split" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we" + " split" +) +some_variable = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at alll".format( + "ha" + ) +) +some_variable = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at allll" + .format("ha") +) +some_variable = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at alllllllllll" + .format("ha") +) +some_variable = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at" + " allllllllllll".format("ha") +) +some_variable = ( + "This is a long string that will end with a method that is not calleddd".format +) +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take" + " place.............", + xyz, + "Some really long string that needs to get split eventually but I'm running out of" + " things to say" + + some_string_inside_a_variable, +) +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take" + " place.............." +) +return ( + "Hi there. This is areally really reallllly long string that needs to be split!!!" +) +ternary_expression = ( + "Short String" + if some_condition + else ( + "This is a really long string that will eventually need to be split right here." + ) +) +return ( + f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaa" +) +return f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaaa" +assert ( + str(result) + == "This long string should be split at some point right close to or around" + " hereeeeeee" +) +assert ( + str(result) + < "This long string should be split at some point right close to or around" + " hereeeeee" +) +assert ( + "A format string: %s" + % "This long string should be split at some point right close to or around" + " hereeeeeee" + != result +) +msg += ( + "This long string should be wrapped in parens at some point right around hereeeee" +) +msg += ( + "This long string should be split at some point right close to or around" + " hereeeeeeee" +) +msg += "This long string should not be split at any point ever since it is just righttt" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.py new file mode 100644 index 0000000000000..74b6cd43a2aa4 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.py @@ -0,0 +1,561 @@ +class A: + def foo(): + result = type(message)("") + + +# Don't merge multiline (e.g. triple-quoted) strings. +def foo(): + query = ( + """SELECT xxxxxxxxxxxxxxxxxxxx(xxx)""" + """ FROM xxxxxxxxxxxxxxxx WHERE xxxxxxxxxx AND xxx <> xxxxxxxxxxxxxx()""") + +# There was a bug where tuples were being identified as long strings. +long_tuple = ('Apple', 'Berry', 'Cherry', 'Dill', 'Evergreen', 'Fig', + 'Grape', 'Harry', 'Iglu', 'Jaguar') + +stupid_format_method_bug = "Some really long string that just so happens to be the {} {} to force the 'format' method to hang over the line length boundary. This is pretty annoying.".format("perfect", "length") + +class A: + def foo(): + os.system("This is a regression test. xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxxx.".format("xxxxxxxxxx", "xxxxxx", "xxxxxxxxxx")) + + +class A: + def foo(): + XXXXXXXXXXXX.append( + ( + "xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx, xxxx_xxxx_xxxxxxxxxx={})".format( + xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx + ), + my_var, + my_other_var, + ) + ) + +class A: + class B: + def foo(): + bar( + ( + "[{}]: xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx={}" + " xxxx_xxxx_xxxxxxxxxx={}, xxxx={})" + .format(xxxx._xxxxxxxxxxxxxx, xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx, xxxxxxx) + ), + varX, + varY, + varZ, + ) + +def foo(xxxx): + for (xxx_xxxx, _xxx_xxx, _xxx_xxxxx, xxx_xxxx) in xxxx: + for xxx in xxx_xxxx: + assert ("x" in xxx) or ( + xxx in xxx_xxx_xxxxx + ), "{0} xxxxxxx xx {1}, xxx {1} xx xxx xx xxxx xx xxx xxxx: xxx xxxx {2}".format( + xxx_xxxx, xxx, xxxxxx.xxxxxxx(xxx_xxx_xxxxx) + ) + +class A: + def disappearing_comment(): + return ( + ( # xx -x xxxxxxx xx xxx xxxxxxx. + '{{xxx_xxxxxxxxxx_xxxxxxxx}} xxx xxxx' + ' {} {{xxxx}} >&2' + .format( + "{xxxx} {xxxxxx}" + if xxxxx.xx_xxxxxxxxxx + else ( # Disappearing Comment + "--xxxxxxx --xxxxxx=x --xxxxxx-xxxxx=xxxxxx" + " --xxxxxx-xxxx=xxxxxxxxxxx.xxx" + ) + ) + ), + (x, y, z), + ) + +class A: + class B: + def foo(): + xxxxx_xxxx( + xx, "\t" + "@xxxxxx '{xxxx_xxx}\t' > {xxxxxx_xxxx}.xxxxxxx;" + "{xxxx_xxx} >> {xxxxxx_xxxx}.xxxxxxx 2>&1; xx=$$?;" + "xxxx $$xx" + .format(xxxx_xxx=xxxx_xxxxxxx, xxxxxx_xxxx=xxxxxxx + "/" + xxxx_xxx_xxxx, x=xxx_xxxxx_xxxxx_xxx), + x, + y, + z, + ) + +func_call_where_string_arg_has_method_call_and_bad_parens( + ( + "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll.".format("formatting") + ), +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + ( + "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll." % "formatting" + ), +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + ( + "A long string with {}. This {} is so long that it is ridiculous. It can't fit on one line at alllll." % ("formatting", "string") + ), +) + +class A: + def append(self): + if True: + xxxx.xxxxxxx.xxxxx( ('xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx' + % (len(self) + 1, + xxxx.xxxxxxxxxx, + xxxx.xxxxxxxxxx)) + + (' %.3f (%s) to %.3f (%s).\n' + % (xxxx.xxxxxxxxx, + xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx), + x, + xxxx.xxxxxxxxxxxxxx( xx) + ))) + +class A: + def foo(): + some_func_call( + 'xxxxxxxxxx', + ( + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + "\"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; " + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" " + ), + None, + ('xxxxxxxxxxx',), + ), + +class A: + def foo(): + some_func_call( + ( + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; " + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" " + ), + None, + ('xxxxxxxxxxx',), + ), + +xxxxxxx = { 'xx' : 'xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} \ +-xx {1} -xx xxx=xxx_xxxx,xxx_xx,xxx_xxx,xxx_xxxx,xxx_xx,xxx_xxx |\ + xxxxxx -x xxxxxxxx -x xxxxxxxx -x', + 'xx' : 'xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} \ +-xx {1} -xx xxx=xxx_xxxx_xxx_xxxx,xxx_xx_xxx_xxxx,xxx_xxxx_xxx_xxxx,\ +xxx_xx_xxxx_xxxx,xxx_xxx_xxxx,xxx_xxx_xxxx xxxx=xxx | xxxxxx -x xxxxxxxx -x xxxxxxxx -x' +} + +class A: + def foo(self): + if True: + xxxxx_xxxxxxxxxxxx('xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx xxxxxxx ' + + 'xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx'.xxxxxx(xxxxxx_xxxxxx_xxx)) + +class A: + class B: + def foo(): + row = { + 'xxxxxxxxxxxxxxx' : xxxxxx_xxxxx_xxxx, + # 'xxxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxx' + 'xxxxxxxxxx' : xxxxx_xxxxx, + } + +class A: + def xxxx_xxx_xx_xxxxxxxxxx_xxxx_xxxxxxxxx(xxxx): + xxxxxxxx = [ + xxxxxxxxxxxxxxxx( + 'xxxx', + xxxxxxxxxxx={ + 'xxxx' : 1.0, + }, + xxxxxx={'xxxxxx 1' : xxxxxx(xxxx='xxxxxx 1', xxxxxx=600.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + 'xxxxxxx', + xxxxxxxxxxx={ + 'xxxx' : 1.0, + }, + xxxxxx={'xxxxxx 1' : xxxxxx(xxxx='xxxxxx 1', xxxxxx=200.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + 'xxxx', + ), + ] + +some_dictionary = { + 'xxxxx006': ['xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx== xxxxx000 xxxxxxxxxx\n', + 'xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx== xxxxx010 xxxxxxxxxx\n'], + 'xxxxx016': ['xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx== xxxxx000 xxxxxxxxxx\n', + 'xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx== xxxxx010 xxxxxxxxxx\n'] +} + +def foo(): + xxx_xxx = ( + 'xxxx xxx xxxxxxxx_xxxx xx "xxxxxxxxxx".' + '\n xxx: xxxxxx xxxxxxxx_xxxx=xxxxxxxxxx' + ) # xxxx xxxxxxxxxx xxxx xx xxxx xx xxx xxxxxxxx xxxxxx xxxxx. + +some_tuple = ("some string", "some string" " which should be joined") + +some_commented_string = ( # This comment stays at the top. + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at" + " allllllllllll".format("ha") # comments here are fine +) + +some_commented_string = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" # But these + " {} that I just can't think of any more good words to say about it at" # comments will stay + " allllllllllll".format("ha") # comments here are fine +) + +lpar_and_rpar_have_comments = func_call( # LPAR Comment + "Long really ridiculous type of string that shouldn't really even exist at all. I mean commmme onnn!!!", # Comma Comment +) # RPAR Comment + +cmd_fstring = ( + f"sudo -E deluge-console info --detailed --sort-reverse=time_added " + f"{'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {{'' if ID is None else ID}} | perl -nE 'print if /^{field}:/'" + +fstring = f"This string really doesn't need to be an {{{{fstring}}}}, but this one most certainly, absolutely {does}." + +fstring = ( + f"We have to remember to escape {braces}." + " Like {these}." + f" But not {this}." +) + +class A: + class B: + def foo(): + st_error = STError( + f"This string ({string_leaf.value}) appears to be pointless (i.e. has" + " no parent)." + ) + +def foo(): + user_regex = _lazy_re_compile( + r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z" # dot-atom + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)', # quoted-string + re.IGNORECASE) + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', # quoted-string + xyz + ) + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', # quoted-string + xyz + ) + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\n" + "Please note that you cannot serialize things like inner " + "classes. Please move the object into the main module " + "body to use migrations.\n" + "For more information, see " + "https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version())) + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\nPlease note that you cannot serialize things like inner classes. Please move the object into the main module body to use migrations.\nFor more information, see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version())) + +x = ( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + +class Step(StepBase): + def who(self): + self.cmd = 'SR AAAA-CORRECT NAME IS {last_name} {first_name}{middle_name} {title}/P{passenger_association}'.format( + last_name=last_name, + first_name=first_name, + middle_name=middle_name, + title=title, + passenger_association=passenger_association, + ) + +xxxxxxx_xxxxxx_xxxxxxx = xxx( + [ + xxxxxxxxxxxx( + xxxxxx_xxxxxxx=( + '((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx = "xxxxxxxxxxxx")) && ' + # xxxxx xxxxxxxxxxxx xxxx xxx (xxxxxxxxxxxxxxxx) xx x xxxxxxxxx xx xxxxxx. + "(x.bbbbbbbbbbbb.xxx != " + '"xxx:xxx:xxx::cccccccccccc:xxxxxxx-xxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxxxx") && ' + ) + ) + ] +) + +if __name__ == "__main__": + for i in range(4, 8): + cmd = ( + r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk '{print $2}'); do kill $pid; done" + % (i) + ) + +def A(): + def B(): + def C(): + def D(): + def E(): + def F(): + def G(): + assert ( + c_float(val[0][0] / val[0][1]).value + == c_float(value[0][0] / value[0][1]).value + ), "%s didn't roundtrip" % tag + +class xxxxxxxxxxxxxxxxxxxxx(xxxx.xxxxxxxxxxxxx): + def xxxxxxx_xxxxxx(xxxx): + assert xxxxxxx_xxxx in [ + x.xxxxx.xxxxxx.xxxxx.xxxxxx, + x.xxxxx.xxxxxx.xxxxx.xxxx, + ], ("xxxxxxxxxxx xxxxxxx xxxx (xxxxxx xxxx) %x xxx xxxxx" % xxxxxxx_xxxx) + +value.__dict__[ + key +] = "test" # set some Thrift field to non-None in the struct aa bb cc dd ee + +RE_ONE_BACKSLASH = { + "asdf_hjkl_jkl": re.compile( + r"(?>\n" +) + +assert str(suffix_arr) == ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) != ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) <= ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) >= ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) < ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) > ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +assert str(suffix_arr) not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + "3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + "5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + "9. You now have a key to add to `{prefix}set api youtube api_key`" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + "9. You now have a key to add to `{prefix}set api youtube api_key`" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{prefix}set api youtube api_key`" +) + +# It shouldn't matter if the string prefixes are capitalized. +temp_msg = ( + F"{F'{humanize_number(pos)}.': <{pound_len+2}} " + F"{balance: <{bal_len + 5}} " + F"<<{author.display_name}>>\n" +) + +fstring = ( + F"We have to remember to escape {braces}." + " Like {these}." + F" But not {this}." +) + +welcome_to_programming = R"hello," R" world!" + +fstring = F"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one." + +x = F"This is a long string which contains an f-expr that should not split {{{[i for i in range(5)]}}}." + +x = ( + "\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}\N{VARIATION SELECTOR-16}" +) + +xxxxxx_xxx_xxxx_xx_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxx_xxxx_xxxxx = xxxx.xxxxxx.xxxxxxxxx.xxxxxxxxxxxxxxxxxxxx( + xx_xxxxxx={ + "x3_xxxxxxxx": "xxx3_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxxxxxx_xxxxxx_xxxxxxx", + }, +) + +# Regression test for https://github.com/psf/black/issues/3117. +some_dict = { + "something_something": + r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t", +} + +# Regression test for https://github.com/psf/black/issues/3459. +xxxx( + empty_str_as_first_split='' + f'xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx ' + 'xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. ' + f'xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}', + empty_u_str_as_first_split=u'' + f'xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx ' + 'xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. ' + f'xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}', +) + +# Regression test for https://github.com/psf/black/issues/3455. +a_dict = { + "/this/is/a/very/very/very/very/very/very/very/very/very/very/long/key/without/spaces": + # And there is a comment before the value + ("item1", "item2", "item3"), +} + +# Regression test for https://github.com/psf/black/issues/3506. +s = ( + "With single quote: ' " + f" {my_dict['foo']}" + ' With double quote: " ' + f' {my_dict["bar"]}' +) + +s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:\'{my_dict["foo"]}\'' diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.py.expect new file mode 100644 index 0000000000000..15c91275afcae --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.py.expect @@ -0,0 +1,680 @@ +class A: + def foo(): + result = type(message)("") + + +# Don't merge multiline (e.g. triple-quoted) strings. +def foo(): + query = ( + """SELECT xxxxxxxxxxxxxxxxxxxx(xxx)""" + """ FROM xxxxxxxxxxxxxxxx WHERE xxxxxxxxxx AND xxx <> xxxxxxxxxxxxxx()""" + ) + + +# There was a bug where tuples were being identified as long strings. +long_tuple = ( + "Apple", + "Berry", + "Cherry", + "Dill", + "Evergreen", + "Fig", + "Grape", + "Harry", + "Iglu", + "Jaguar", +) + +stupid_format_method_bug = ( + "Some really long string that just so happens to be the {} {} to force the 'format'" + " method to hang over the line length boundary. This is pretty annoying.".format( + "perfect", "length" + ) +) + + +class A: + def foo(): + os.system( + "This is a regression test. xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx" + " xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx" + " xxxx.".format("xxxxxxxxxx", "xxxxxx", "xxxxxxxxxx") + ) + + +class A: + def foo(): + XXXXXXXXXXXX.append(( + "xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx, xxxx_xxxx_xxxxxxxxxx={})".format( + xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx + ), + my_var, + my_other_var, + )) + + +class A: + class B: + def foo(): + bar( + "[{}]: xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx={}" + " xxxx_xxxx_xxxxxxxxxx={}, xxxx={})".format( + xxxx._xxxxxxxxxxxxxx, xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx, xxxxxxx + ), + varX, + varY, + varZ, + ) + + +def foo(xxxx): + for xxx_xxxx, _xxx_xxx, _xxx_xxxxx, xxx_xxxx in xxxx: + for xxx in xxx_xxxx: + assert ("x" in xxx) or (xxx in xxx_xxx_xxxxx), ( + "{0} xxxxxxx xx {1}, xxx {1} xx xxx xx xxxx xx xxx xxxx: xxx xxxx {2}" + .format(xxx_xxxx, xxx, xxxxxx.xxxxxxx(xxx_xxx_xxxxx)) + ) + + +class A: + def disappearing_comment(): + return ( + ( # xx -x xxxxxxx xx xxx xxxxxxx. + "{{xxx_xxxxxxxxxx_xxxxxxxx}} xxx xxxx {} {{xxxx}} >&2".format( + "{xxxx} {xxxxxx}" + if xxxxx.xx_xxxxxxxxxx + else ( # Disappearing Comment + "--xxxxxxx --xxxxxx=x --xxxxxx-xxxxx=xxxxxx" + " --xxxxxx-xxxx=xxxxxxxxxxx.xxx" + ) + ) + ), + (x, y, z), + ) + + +class A: + class B: + def foo(): + xxxxx_xxxx( + xx, + "\t" + "@xxxxxx '{xxxx_xxx}\t' > {xxxxxx_xxxx}.xxxxxxx;" + "{xxxx_xxx} >> {xxxxxx_xxxx}.xxxxxxx 2>&1; xx=$$?;" + "xxxx $$xx".format( + xxxx_xxx=xxxx_xxxxxxx, + xxxxxx_xxxx=xxxxxxx + "/" + xxxx_xxx_xxxx, + x=xxx_xxxxx_xxxxx_xxx, + ), + x, + y, + z, + ) + + +func_call_where_string_arg_has_method_call_and_bad_parens( + "A long string with {}. This string is so long that it is ridiculous. It can't fit" + " on one line at alllll.".format("formatting"), +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + "A long string with {}. This string is so long that it is ridiculous. It can't fit" + " on one line at alllll." % "formatting", +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + "A long string with {}. This {} is so long that it is ridiculous. It can't fit on" + " one line at alllll." % ("formatting", "string"), +) + + +class A: + def append(self): + if True: + xxxx.xxxxxxx.xxxxx( + "xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx" + % (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx) + + " %.3f (%s) to %.3f (%s).\n" + % ( + xxxx.xxxxxxxxx, + xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx), + x, + xxxx.xxxxxxxxxxxxxx(xx), + ) + ) + + +class A: + def foo(): + some_func_call( + "xxxxxxxxxx", + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + '"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; ' + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" ", + None, + ("xxxxxxxxxxx",), + ), + + +class A: + def foo(): + some_func_call( + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; " + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" ", + None, + ("xxxxxxxxxxx",), + ), + + +xxxxxxx = { + "xx": ( + "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} -xx {1} -xx" + " xxx=xxx_xxxx,xxx_xx,xxx_xxx,xxx_xxxx,xxx_xx,xxx_xxx | xxxxxx -x xxxxxxxx -x" + " xxxxxxxx -x" + ), + "xx": ( + "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} -xx {1} -xx" + " xxx=xxx_xxxx_xxx_xxxx,xxx_xx_xxx_xxxx,xxx_xxxx_xxx_xxxx,xxx_xx_xxxx_xxxx,xxx_xxx_xxxx,xxx_xxx_xxxx" + " xxxx=xxx | xxxxxx -x xxxxxxxx -x xxxxxxxx -x" + ), +} + + +class A: + def foo(self): + if True: + xxxxx_xxxxxxxxxxxx( + "xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx" + " xxxxxxx " + + "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx" + .xxxxxx(xxxxxx_xxxxxx_xxx) + ) + + +class A: + class B: + def foo(): + row = { + "xxxxxxxxxxxxxxx": xxxxxx_xxxxx_xxxx, + # 'xxxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxx' + "xxxxxxxxxx": xxxxx_xxxxx, + } + + +class A: + def xxxx_xxx_xx_xxxxxxxxxx_xxxx_xxxxxxxxx(xxxx): + xxxxxxxx = [ + xxxxxxxxxxxxxxxx( + "xxxx", + xxxxxxxxxxx={ + "xxxx": 1.0, + }, + xxxxxx={"xxxxxx 1": xxxxxx(xxxx="xxxxxx 1", xxxxxx=600.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + "xxxxxxx", + xxxxxxxxxxx={ + "xxxx": 1.0, + }, + xxxxxx={"xxxxxx 1": xxxxxx(xxxx="xxxxxx 1", xxxxxx=200.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + "xxxx", + ), + ] + + +some_dictionary = { + "xxxxx006": [ + ( + "xxx-xxx" + " xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx==" + " xxxxx000 xxxxxxxxxx\n" + ), + ( + "xxx-xxx" + " xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx==" + " xxxxx010 xxxxxxxxxx\n" + ), + ], + "xxxxx016": [ + ( + "xxx-xxx" + " xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx==" + " xxxxx000 xxxxxxxxxx\n" + ), + ( + "xxx-xxx" + " xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx==" + " xxxxx010 xxxxxxxxxx\n" + ), + ], +} + + +def foo(): + xxx_xxx = ( # xxxx xxxxxxxxxx xxxx xx xxxx xx xxx xxxxxxxx xxxxxx xxxxx. + 'xxxx xxx xxxxxxxx_xxxx xx "xxxxxxxxxx".\n xxx: xxxxxx xxxxxxxx_xxxx=xxxxxxxxxx' + ) + + +some_tuple = ("some string", "some string which should be joined") + +some_commented_string = ( # This comment stays at the top. + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at" + " allllllllllll".format("ha") # comments here are fine +) + +some_commented_string = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" # But these + " {} that I just can't think of any more good words to say about it at" # comments will stay + " allllllllllll".format("ha") # comments here are fine +) + +lpar_and_rpar_have_comments = func_call( # LPAR Comment + "Long really ridiculous type of string that shouldn't really even exist at all. I" + " mean commmme onnn!!!", # Comma Comment +) # RPAR Comment + +cmd_fstring = ( + "sudo -E deluge-console info --detailed --sort-reverse=time_added " + f"{'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = ( + "sudo -E deluge-console info --detailed --sort-reverse=time_added" + f" {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = ( + "sudo -E deluge-console info --detailed --sort-reverse=time_added" + f" {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = ( + "sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is" + f" None else ID}} | perl -nE 'print if /^{field}:/'" +) + +fstring = ( + "This string really doesn't need to be an {{fstring}}, but this one most" + f" certainly, absolutely {does}." +) + +fstring = f"We have to remember to escape {braces}. Like {{these}}. But not {this}." + + +class A: + class B: + def foo(): + st_error = STError( + f"This string ({string_leaf.value}) appears to be pointless (i.e. has" + " no parent)." + ) + + +def foo(): + user_regex = _lazy_re_compile( + r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z" # dot-atom + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)', # quoted-string + re.IGNORECASE, + ) + + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # quoted-string + xyz, + ) + + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # quoted-string + xyz, + ) + + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\n" + "Please note that you cannot serialize things like inner " + "classes. Please move the object into the main module " + "body to use migrations.\n" + "For more information, see " + "https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version()) + ) + + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\nPlease note that you cannot" + " serialize things like inner classes. Please move the object into" + " the main module body to use migrations.\nFor more information," + " see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version()) + ) + + +x = ( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + + +class Step(StepBase): + def who(self): + self.cmd = ( + "SR AAAA-CORRECT NAME IS {last_name} {first_name}{middle_name}" + " {title}/P{passenger_association}".format( + last_name=last_name, + first_name=first_name, + middle_name=middle_name, + title=title, + passenger_association=passenger_association, + ) + ) + + +xxxxxxx_xxxxxx_xxxxxxx = xxx([ + xxxxxxxxxxxx( + xxxxxx_xxxxxxx=( + '((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx =' + ' "xxxxxxxxxxxx")) && ' + # xxxxx xxxxxxxxxxxx xxxx xxx (xxxxxxxxxxxxxxxx) xx x xxxxxxxxx xx xxxxxx. + "(x.bbbbbbbbbbbb.xxx != " + '"xxx:xxx:xxx::cccccccccccc:xxxxxxx-xxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxxxx") && ' + ) + ) +]) + +if __name__ == "__main__": + for i in range(4, 8): + cmd = ( + r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk" + r" '{print $2}'); do kill $pid; done" % (i) + ) + + +def A(): + def B(): + def C(): + def D(): + def E(): + def F(): + def G(): + assert ( + c_float(val[0][0] / val[0][1]).value + == c_float(value[0][0] / value[0][1]).value + ), "%s didn't roundtrip" % tag + + +class xxxxxxxxxxxxxxxxxxxxx(xxxx.xxxxxxxxxxxxx): + def xxxxxxx_xxxxxx(xxxx): + assert xxxxxxx_xxxx in [ + x.xxxxx.xxxxxx.xxxxx.xxxxxx, + x.xxxxx.xxxxxx.xxxxx.xxxx, + ], ( + "xxxxxxxxxxx xxxxxxx xxxx (xxxxxx xxxx) %x xxx xxxxx" % xxxxxxx_xxxx + ) + + +value.__dict__[key] = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) + +RE_ONE_BACKSLASH = { + "asdf_hjkl_jkl": re.compile( + r"(?>\n" +) + +assert ( + str(suffix_arr) + == "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + != "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + <= "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + >= "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + < "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + > "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$'," + " 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$'," + " 'ykangaroo$']" +) +assert ( + str(suffix_arr) + not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$'," + " 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$'," + " 'rykangaroo$', 'ykangaroo$']" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + f"(https://console.developers.google.com/)" + f"2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + f"4. In the list of APIs choose or search for YouTube Data API v3 and " + f"click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + f"6. Click on Create Credential at the top." + f'7. At the top click the link for "API key".' + f"8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{{prefix}}set api youtube api_key`" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + f"(https://console.developers.google.com/)" + f"2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + f"4. In the list of APIs choose or search for YouTube Data API v3 and " + f"click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + f"6. Click on Create Credential at the top." + f'7. At the top click the link for "API key".' + f"8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{{prefix}}set api youtube api_key`" +) +message = ( + "1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + "3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + "5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{prefix}set api youtube api_key`" +) + +# It shouldn't matter if the string prefixes are capitalized. +temp_msg = ( + f"{F'{humanize_number(pos)}.': <{pound_len+2}} " + f"{balance: <{bal_len + 5}} " + f"<<{author.display_name}>>\n" +) + +fstring = f"We have to remember to escape {braces}. Like {{these}}. But not {this}." + +welcome_to_programming = R"hello," R" world!" + +fstring = ( + f"f-strings definitely make things more {difficult} than they need to be for" + " {black}. But boy they sure are handy. The problem is that some lines will need" + f" to have the 'f' whereas others do not. This {line}, for example, needs one." +) + +x = ( + "This is a long string which contains an f-expr that should not split" + f" {{{[i for i in range(5)]}}}." +) + +x = ( + "\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}\N{VARIATION SELECTOR-16}" +) + +xxxxxx_xxx_xxxx_xx_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxx_xxxx_xxxxx = xxxx.xxxxxx.xxxxxxxxx.xxxxxxxxxxxxxxxxxxxx( + xx_xxxxxx={ + "x3_xxxxxxxx": ( + "xxx3_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxxxxxx_xxxxxx_xxxxxxx" + ), + }, +) + +# Regression test for https://github.com/psf/black/issues/3117. +some_dict = { + "something_something": ( + r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + ), +} + +# Regression test for https://github.com/psf/black/issues/3459. +xxxx( + empty_str_as_first_split=( + "" + f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " + "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " + f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}" + ), + empty_u_str_as_first_split=( + "" + f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " + "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " + f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}" + ), +) + +# Regression test for https://github.com/psf/black/issues/3455. +a_dict = { + "/this/is/a/very/very/very/very/very/very/very/very/very/very/long/key/without/spaces": + # And there is a comment before the value + ("item1", "item2", "item3"), +} + +# Regression test for https://github.com/psf/black/issues/3506. +s = f"With single quote: ' {my_dict['foo']} With double quote: \" {my_dict['bar']}" + +s = ( + "Lorem Ipsum is simply dummy text of the printing and typesetting" + f" industry:'{my_dict['foo']}'" +) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.py new file mode 100644 index 0000000000000..4907fec71c454 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.py @@ -0,0 +1,28 @@ +def func( + arg1, + arg2, +) -> Set["this_is_a_very_long_module_name.AndAVeryLongClasName" + ".WithAVeryVeryVeryVeryVeryLongSubClassName"]: + pass + + +def func( + argument: ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" + ), +) -> ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" +): + pass + + +def func( + argument: ( + "int |" + "str" + ), +) -> Set["int |" + " str"]: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.py.expect new file mode 100644 index 0000000000000..679df21eedbff --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.py.expect @@ -0,0 +1,26 @@ +def func( + arg1, + arg2, +) -> Set[ + "this_is_a_very_long_module_name.AndAVeryLongClasName" + ".WithAVeryVeryVeryVeryVeryLongSubClassName" +]: + pass + + +def func( + argument: ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" + ), +) -> ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" +): + pass + + +def func( + argument: "int |" "str", +) -> Set["int |" " str"]: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.py new file mode 100644 index 0000000000000..717f7b52e80b2 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.py @@ -0,0 +1,175 @@ +"""cow +say""", +call(3, "dogsay", textwrap.dedent("""dove + coo""" % "cowabunga")) +call(3, "dogsay", textwrap.dedent("""dove +coo""" % "cowabunga")) +call(3, textwrap.dedent("""cow + moo""" % "cowabunga"), "dogsay") +call(3, "dogsay", textwrap.dedent("""crow + caw""" % "cowabunga"),) +call(3, textwrap.dedent("""cat + meow""" % "cowabunga"), {"dog", "say"}) +call(3, {"dog", "say"}, textwrap.dedent("""horse + neigh""" % "cowabunga")) +call(3, {"dog", "say"}, textwrap.dedent("""pig + oink""" % "cowabunga"),) +textwrap.dedent("""A one-line triple-quoted string.""") +textwrap.dedent("""A two-line triple-quoted string +since it goes to the next line.""") +textwrap.dedent("""A three-line triple-quoted string +that not only goes to the next line +but also goes one line beyond.""") +textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""") +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""")) +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {config_filename} file contents. +""".format("config_filename", config_filename))) +# Another use case +data = yaml.load("""\ +a: 1 +b: 2 +""") +data = yaml.load("""\ +a: 1 +b: 2 +""",) +data = yaml.load( + """\ + a: 1 + b: 2 +""" +) + +MULTILINE = """ +foo +""".replace("\n", "") +generated_readme = lambda project_name: """ +{} + + +""".strip().format(project_name) +parser.usage += """ +Custom extra help summary. + +Extra test: +- with +- bullets +""" + + +def get_stuff(cr, value): + # original + cr.execute(""" + SELECT whatever + FROM some_table t + WHERE id = %s + """, [value]) + return cr.fetchone() + + +def get_stuff(cr, value): + # preferred + cr.execute( + """ + SELECT whatever + FROM some_table t + WHERE id = %s + """, + [value], + ) + return cr.fetchone() + + +call(arg1, arg2, """ +short +""", arg3=True) +test_vectors = [ + "one-liner\n", + "two\nliner\n", + """expressed +as a three line +mulitline string""", +] + +_wat = re.compile( + r""" + regex + """, + re.MULTILINE | re.VERBOSE, +) +dis_c_instance_method = """\ +%3d 0 LOAD_FAST 1 (x) + 2 LOAD_CONST 1 (1) + 4 COMPARE_OP 2 (==) + 6 LOAD_FAST 0 (self) + 8 STORE_ATTR 0 (x) + 10 LOAD_CONST 0 (None) + 12 RETURN_VALUE +""" % (_C.__init__.__code__.co_firstlineno + 1,) +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually {verb} the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {file_type} file contents. +""".format(verb="using", file_type="test"))) +{"""cow +moos"""} +["""cow +moos"""] +["""cow +moos""", """dog +woofs +and +barks"""] +def dastardly_default_value( + cow: String = json.loads("""this +is +quite +the +dastadardly +value!"""), + **kwargs, +): + pass + +print(f""" + This {animal} + moos and barks +{animal} say +""") +msg = f"""The arguments {bad_arguments} were passed in. +Please use `--build-option` instead, +`--global-option` is reserved to flags like `--verbose` or `--quiet`. +""" + +this_will_become_one_line = ( + "a" + "b" + "c" +) + +this_will_stay_on_three_lines = ( + "a" # comment + "b" + "c" +) + +this_will_also_become_one_line = ( # comment + "a" + "b" + "c" +) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.py.expect new file mode 100644 index 0000000000000..3983178da9bf8 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.py.expect @@ -0,0 +1,209 @@ +"""cow +say""", +call( + 3, + "dogsay", + textwrap.dedent("""dove + coo""" % "cowabunga"), +) +call( + 3, + "dogsay", + textwrap.dedent("""dove +coo""" % "cowabunga"), +) +call( + 3, + textwrap.dedent("""cow + moo""" % "cowabunga"), + "dogsay", +) +call( + 3, + "dogsay", + textwrap.dedent("""crow + caw""" % "cowabunga"), +) +call( + 3, + textwrap.dedent("""cat + meow""" % "cowabunga"), + {"dog", "say"}, +) +call( + 3, + {"dog", "say"}, + textwrap.dedent("""horse + neigh""" % "cowabunga"), +) +call( + 3, + {"dog", "say"}, + textwrap.dedent("""pig + oink""" % "cowabunga"), +) +textwrap.dedent("""A one-line triple-quoted string.""") +textwrap.dedent("""A two-line triple-quoted string +since it goes to the next line.""") +textwrap.dedent("""A three-line triple-quoted string +that not only goes to the next line +but also goes one line beyond.""") +textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""") +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""")) +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {config_filename} file contents. +""".format("config_filename", config_filename))) +# Another use case +data = yaml.load("""\ +a: 1 +b: 2 +""") +data = yaml.load( + """\ +a: 1 +b: 2 +""", +) +data = yaml.load("""\ + a: 1 + b: 2 +""") + +MULTILINE = """ +foo +""".replace("\n", "") +generated_readme = lambda project_name: """ +{} + + +""".strip().format(project_name) +parser.usage += """ +Custom extra help summary. + +Extra test: +- with +- bullets +""" + + +def get_stuff(cr, value): + # original + cr.execute( + """ + SELECT whatever + FROM some_table t + WHERE id = %s + """, + [value], + ) + return cr.fetchone() + + +def get_stuff(cr, value): + # preferred + cr.execute( + """ + SELECT whatever + FROM some_table t + WHERE id = %s + """, + [value], + ) + return cr.fetchone() + + +call( + arg1, + arg2, + """ +short +""", + arg3=True, +) +test_vectors = [ + "one-liner\n", + "two\nliner\n", + """expressed +as a three line +mulitline string""", +] + +_wat = re.compile( + r""" + regex + """, + re.MULTILINE | re.VERBOSE, +) +dis_c_instance_method = """\ +%3d 0 LOAD_FAST 1 (x) + 2 LOAD_CONST 1 (1) + 4 COMPARE_OP 2 (==) + 6 LOAD_FAST 0 (self) + 8 STORE_ATTR 0 (x) + 10 LOAD_CONST 0 (None) + 12 RETURN_VALUE +""" % (_C.__init__.__code__.co_firstlineno + 1,) +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually {verb} the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {file_type} file contents. +""".format(verb="using", file_type="test"))) +{"""cow +moos"""} +["""cow +moos"""] +[ + """cow +moos""", + """dog +woofs +and +barks""", +] + + +def dastardly_default_value( + cow: String = json.loads("""this +is +quite +the +dastadardly +value!"""), + **kwargs, +): + pass + + +print(f""" + This {animal} + moos and barks +{animal} say +""") +msg = f"""The arguments {bad_arguments} were passed in. +Please use `--build-option` instead, +`--global-option` is reserved to flags like `--verbose` or `--quiet`. +""" + +this_will_become_one_line = "abc" + +this_will_stay_on_three_lines = ( + "a" # comment + "b" + "c" +) + +this_will_also_become_one_line = "abc" # comment diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.py new file mode 100644 index 0000000000000..43ba2bd20233a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.py @@ -0,0 +1,29 @@ +def line_before_docstring(): + + """Please move me up""" + + +class LineBeforeDocstring: + + """Please move me up""" + + +class EvenIfThereIsAMethodAfter: + + """I'm the docstring""" + def method(self): + pass + + +class TwoLinesBeforeDocstring: + + + """I want to be treated the same as if I were closer""" + + +class MultilineDocstringsAsWell: + + """I'm so far + + and on so many lines... + """ diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.py.expect new file mode 100644 index 0000000000000..78604d9c9247a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.py.expect @@ -0,0 +1,24 @@ +def line_before_docstring(): + """Please move me up""" + + +class LineBeforeDocstring: + """Please move me up""" + + +class EvenIfThereIsAMethodAfter: + """I'm the docstring""" + + def method(self): + pass + + +class TwoLinesBeforeDocstring: + """I want to be treated the same as if I were closer""" + + +class MultilineDocstringsAsWell: + """I'm so far + + and on so many lines... + """ diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.py new file mode 100644 index 0000000000000..98b6ac56a2048 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.py @@ -0,0 +1,7 @@ +match x: + case "abcd" | "abcd" | "abcd" : + pass + case "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd" | "abcd": + pass + case xxxxxxxxxxxxxxxxxxxxxxx: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.py.expect new file mode 100644 index 0000000000000..c60e5770a7a41 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_long.py.expect @@ -0,0 +1,23 @@ +match x: + case "abcd" | "abcd" | "abcd": + pass + case ( + "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + | "abcd" + ): + pass + case xxxxxxxxxxxxxxxxxxxxxxx: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.py new file mode 100644 index 0000000000000..002ceea330686 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.py @@ -0,0 +1,14 @@ +match maybe, multiple: + case perhaps, 5: + pass + case perhaps, 6,: + pass + + +match more := (than, one), indeed,: + case _, (5, 6): + pass + case [[5], (6)], [7],: + pass + case _: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.py.expect new file mode 100644 index 0000000000000..6e8ef32f18157 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.py.expect @@ -0,0 +1,20 @@ +match maybe, multiple: + case perhaps, 5: + pass + case ( + perhaps, + 6, + ): + pass + + +match more := (than, one), indeed,: + case _, (5, 6): + pass + case ( + [[5], (6)], + [7], + ): + pass + case _: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.py new file mode 100644 index 0000000000000..dff98530388cf --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.py @@ -0,0 +1,2 @@ +x[(a:=0):] +x[:(a:=0)] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.py.expect new file mode 100644 index 0000000000000..0ae5b9769d12c --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.py.expect @@ -0,0 +1,2 @@ +x[(a := 0):] +x[:(a := 0)] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.py new file mode 100644 index 0000000000000..ab71177d2e1d7 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.py @@ -0,0 +1,20 @@ +("" % a) ** 2 +("" % a)[0] +("" % a)() +("" % a).b + +2 * ("" % a) +2 @ ("" % a) +2 / ("" % a) +2 // ("" % a) +2 % ("" % a) ++("" % a) +b + ("" % a) +-("" % a) +b - ("" % a) +b + -("" % a) +~("" % a) +2 ** ("" % a) +await ("" % a) +b[("" % a)] +b(("" % a)) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.py.expect new file mode 100644 index 0000000000000..bd77adeeb7524 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.py.expect @@ -0,0 +1,20 @@ +("" % a) ** 2 +("" % a)[0] +("" % a)() +("" % a).b + +2 * ("" % a) +2 @ ("" % a) +2 / ("" % a) +2 // ("" % a) +2 % ("" % a) ++("" % a) +b + "" % a +-("" % a) +b - "" % a +b + -("" % a) +~("" % a) +2 ** ("" % a) +await ("" % a) +b[("" % a)] +b(("" % a)) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.py new file mode 100644 index 0000000000000..af361012ea829 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.py @@ -0,0 +1,11 @@ +a = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1 +b = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1 +c = 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 ** 1 +d = 1**1 ** 1**1 ** 1**1 ** 1**1 ** 1**1**1 ** 1 ** 1**1 ** 1**1**1**1**1 ** 1 ** 1**1**1 **1**1** 1 ** 1 ** 1 +e = 𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟 +f = 𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟 + +a = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0 +b = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0 +c = 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 ** 1.0 +d = 1.0**1.0 ** 1.0**1.0 ** 1.0**1.0 ** 1.0**1.0 ** 1.0**1.0**1.0 ** 1.0 ** 1.0**1.0 ** 1.0**1.0**1.0 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.py.expect new file mode 100644 index 0000000000000..da8b91530b81d --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_power_op_spacing.py.expect @@ -0,0 +1,83 @@ +a = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1 +b = ( + 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 + ** 1 +) +c = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1 +d = 1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1**1 +e = 𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟**𨉟 +f = ( + 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 + ** 𨉟 +) + +a = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0 +b = ( + 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 + ** 1.0 +) +c = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0 +d = 1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0**1.0 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.py new file mode 100644 index 0000000000000..f3d9fd672515c --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.py @@ -0,0 +1,106 @@ +first_item, second_item = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure it works when the RHS only has one pair of (optional) parens. +first_item, second_item = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +# Make sure chaining assignments work. +first_item, second_item, third_item, forth_item = m["everything"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure when the RHS's first split at the non-optional paren fits, +# we split there instead of the outer RHS optional paren. +first_item, second_item = some_looooooooong_module.some_loooooog_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = everything = some_looooong_function_name( + first_argument, second_argument, third_argument +) + + +# Make sure unsplittable type ignore won't be moved. +some_kind_of_table[some_key] = util.some_function( # type: ignore # noqa: E501 + some_arg +).intersection(pk_cols) + +some_kind_of_table[ + some_key +] = lambda obj: obj.some_long_named_method() # type: ignore # noqa: E501 + +some_kind_of_table[ + some_key # type: ignore # noqa: E501 +] = lambda obj: obj.some_long_named_method() + + +# Make when when the left side of assignment plus the opening paren "... = (" is +# exactly line length limit + 1, it won't be split like that. +xxxxxxxxx_yyy_zzzzzzzz[ + xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1) +] = 1 + + +# Right side of assignment contains un-nested pairs of inner parens. +some_kind_of_instance.some_kind_of_map[a_key] = ( + isinstance(some_var, SomeClass) + and table.something_and_something != table.something_else +) or ( + isinstance(some_other_var, BaseClass) and table.something != table.some_other_thing +) + +# Multiple targets +a = b = ( + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) + +a = b = c = d = e = f = g = ( + hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +) = i = j = ( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk +) + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = c + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = ( + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) = ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.py.expect new file mode 100644 index 0000000000000..f3d9fd672515c --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.py.expect @@ -0,0 +1,106 @@ +first_item, second_item = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure it works when the RHS only has one pair of (optional) parens. +first_item, second_item = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +# Make sure chaining assignments work. +first_item, second_item, third_item, forth_item = m["everything"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure when the RHS's first split at the non-optional paren fits, +# we split there instead of the outer RHS optional paren. +first_item, second_item = some_looooooooong_module.some_loooooog_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = everything = some_looooong_function_name( + first_argument, second_argument, third_argument +) + + +# Make sure unsplittable type ignore won't be moved. +some_kind_of_table[some_key] = util.some_function( # type: ignore # noqa: E501 + some_arg +).intersection(pk_cols) + +some_kind_of_table[ + some_key +] = lambda obj: obj.some_long_named_method() # type: ignore # noqa: E501 + +some_kind_of_table[ + some_key # type: ignore # noqa: E501 +] = lambda obj: obj.some_long_named_method() + + +# Make when when the left side of assignment plus the opening paren "... = (" is +# exactly line length limit + 1, it won't be split like that. +xxxxxxxxx_yyy_zzzzzzzz[ + xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1) +] = 1 + + +# Right side of assignment contains un-nested pairs of inner parens. +some_kind_of_instance.some_kind_of_map[a_key] = ( + isinstance(some_var, SomeClass) + and table.something_and_something != table.something_else +) or ( + isinstance(some_other_var, BaseClass) and table.something != table.some_other_thing +) + +# Multiple targets +a = b = ( + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) + +a = b = c = d = e = f = g = ( + hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +) = i = j = ( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk +) + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = c + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = ( + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) = ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.py new file mode 100644 index 0000000000000..474130e48f38f --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.py @@ -0,0 +1,7 @@ +# Long string example +def frobnicate() -> "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]": + pass + +# splitting the string breaks if there's any parameters +def frobnicate(a) -> "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]": + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.py.expect new file mode 100644 index 0000000000000..610e399b4ae14 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.py.expect @@ -0,0 +1,13 @@ +# Long string example +def frobnicate() -> ( + "ThisIsTrulyUnreasonablyExtremelyLongClassName |" + " list[ThisIsTrulyUnreasonablyExtremelyLongClassName]" +): + pass + + +# splitting the string breaks if there's any parameters +def frobnicate( + a, +) -> "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]": + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.py new file mode 100644 index 0000000000000..812febcf2a19f --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.py @@ -0,0 +1,8 @@ +foo = 123 # fmt: skip # noqa: E501 # pylint +bar = ( + 123 , + ( 1 + 5 ) # pylint # fmt:skip +) +baz = "a" + "b" # pylint; fmt: skip; noqa: E501 +skip_will_not_work = "a" + "b" # pylint fmt:skip +skip_will_not_work2 = "a" + "b" # some text; fmt:skip happens to be part of it diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.py.expect new file mode 100644 index 0000000000000..d799b0c790e27 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.py.expect @@ -0,0 +1,8 @@ +foo = 123 # fmt: skip # noqa: E501 # pylint +bar = ( + 123 , + ( 1 + 5 ) # pylint # fmt:skip +) +baz = "a" + "b" # pylint; fmt: skip; noqa: E501 +skip_will_not_work = "a" + "b" # pylint fmt:skip +skip_will_not_work2 = "a" + "b" # some text; fmt:skip happens to be part of it diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.py new file mode 100644 index 0000000000000..24c53091b9002 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.py @@ -0,0 +1,24 @@ +e = { + "a": fun(msg, "ts"), + "longggggggggggggggid": ..., + "longgggggggggggggggggggkey": ..., "created": ... + # "longkey": ... +} +f = [ + arg1, + arg2, + arg3, arg4 + # comment +] +g = ( + arg1, + arg2, + arg3, arg4 + # comment +) +h = { + arg1, + arg2, + arg3, arg4 + # comment +} diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.py.expect new file mode 100644 index 0000000000000..1b2bafa0287ec --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_trailing_comma.py.expect @@ -0,0 +1,28 @@ +e = { + "a": fun(msg, "ts"), + "longggggggggggggggid": ..., + "longgggggggggggggggggggkey": ..., + "created": ..., + # "longkey": ... +} +f = [ + arg1, + arg2, + arg3, + arg4, + # comment +] +g = ( + arg1, + arg2, + arg3, + arg4, + # comment +) +h = { + arg1, + arg2, + arg3, + arg4, + # comment +} diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.py new file mode 100644 index 0000000000000..1f2a3b903f08c --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.py @@ -0,0 +1,5 @@ +x[a:=0] +x[a := 0] +x[a := 0, b := 1] +x[5, b := 0] +x[a:=0,b:=1] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.py.expect new file mode 100644 index 0000000000000..1b3b90bcc0305 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/py310_pep572.py.expect @@ -0,0 +1,5 @@ +x[a := 0] +x[a := 0] +x[a := 0, b := 1] +x[5, b := 0] +x[a := 0, b := 1] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_37/python37.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python37.py similarity index 95% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_37/python37.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/python37.py index 01fd7eede3f3a..3fcf6e0ffc530 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_37/python37.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python37.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3.7 - - def f(): return (i * 2 async for i in arange(42)) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_37/python37.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python37.py.expect similarity index 95% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_37/python37.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/python37.py.expect index 01fd7eede3f3a..3fcf6e0ffc530 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_37/python37.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python37.py.expect @@ -1,6 +1,3 @@ -#!/usr/bin/env python3.7 - - def f(): return (i * 2 async for i in arange(42)) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/python38.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python38.py similarity index 93% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_38/python38.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/python38.py index 391b52f8ce511..54d87b3400eb1 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/python38.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python38.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3.8 - - def starred_return(): my_list = ["value2", "value3"] return "value1", *my_list diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/python38.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python38.py.expect similarity index 93% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_38/python38.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/python38.py.expect index 5df012410a30b..76e2ae438e5ab 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_38/python38.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python38.py.expect @@ -1,6 +1,3 @@ -#!/usr/bin/env python3.8 - - def starred_return(): my_list = ["value2", "value3"] return "value1", *my_list diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_39/python39.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python39.py similarity index 92% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_39/python39.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/python39.py index 227faca09a1ab..c0434277f66a0 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_39/python39.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python39.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3.9 - @relaxed_decorator[0] def f(): ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_39/python39.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python39.py.expect similarity index 92% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_39/python39.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/python39.py.expect index 4af4beebb250e..99db2993cb218 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_39/python39.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/python39.py.expect @@ -1,6 +1,3 @@ -#!/usr/bin/env python3.9 - - @relaxed_decorator[0] def f(): ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.options.json new file mode 100644 index 0000000000000..ce7c52b163497 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.options.json @@ -0,0 +1 @@ +{"preview": "enabled"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.py new file mode 100644 index 0000000000000..72fe443843e9a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.py @@ -0,0 +1,15 @@ +class C: + + r"""Raw""" + +def f(): + + r"""Raw""" + +class SingleQuotes: + + + r'''Raw''' + +class UpperCaseR: + R"""Raw""" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.py.expect new file mode 100644 index 0000000000000..5be480f7f0e89 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.py.expect @@ -0,0 +1,14 @@ +class C: + r"""Raw""" + + +def f(): + r"""Raw""" + + +class SingleQuotes: + r'''Raw''' + + +class UpperCaseR: + R"""Raw""" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_await_parens.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_await_parens.py similarity index 90% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_await_parens.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_await_parens.py index 6b8d15f755cfc..f65336615dcc2 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_await_parens.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_await_parens.py @@ -79,3 +79,12 @@ async def main(): async def main(): await (yield) + +async def main(): + await (a ** b) + await (a[b] ** c) + await (a ** b[c]) + await ((a + b) ** (c + d)) + await (a + b) + await (a[b]) + await (a[b ** c]) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_await_parens.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_await_parens.py.expect similarity index 90% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_await_parens.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_await_parens.py.expect index 91e7eb39e1fab..58e879d21726d 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_await_parens.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_await_parens.py.expect @@ -91,3 +91,13 @@ async def main(): async def main(): await (yield) + + +async def main(): + await (a**b) + await (a[b] ** c) + await (a ** b[c]) + await ((a + b) ** (c + d)) + await (a + b) + await a[b] + await a[b**c] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_except_parens.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_except_parens.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_except_parens.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_except_parens.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_except_parens.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_except_parens.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_except_parens.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_except_parens.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_for_brackets.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_for_brackets.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_for_brackets.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_for_brackets.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_for_brackets.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_for_brackets.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_for_brackets.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_for_brackets.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_newline_after_code_block_open.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_newline_after_code_block_open.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_newline_after_code_block_open.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_newline_after_code_block_open.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_newline_after_code_block_open.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_newline_after_code_block_open.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_newline_after_code_block_open.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_newline_after_code_block_open.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/remove_newline_after_match.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_newline_after_match.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/remove_newline_after_match.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_newline_after_match.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/remove_newline_after_match.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_newline_after_match.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/remove_newline_after_match.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_newline_after_match.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_parens.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_parens.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_parens.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_parens.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_parens.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_parens.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_parens.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_parens.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_39/remove_with_brackets.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_with_brackets.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_39/remove_with_brackets.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_with_brackets.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_39/remove_with_brackets.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_with_brackets.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_39/remove_with_brackets.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_with_brackets.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/return_annotation_brackets.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/return_annotation_brackets.py similarity index 93% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/return_annotation_brackets.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/return_annotation_brackets.py index 3e6b45147f2e5..8322c4c7ac1f2 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/return_annotation_brackets.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/return_annotation_brackets.py @@ -86,3 +86,8 @@ def foo() -> tuple[loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo # Magic trailing comma example def foo() -> tuple[int, int, int,]: return 2 + +# Magic trailing comma example, with params +# this is broken - the trailing comma is transferred to the param list. Fixed in preview +def foo(a,b) -> tuple[int, int, int,]: + return 2 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/return_annotation_brackets.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/return_annotation_brackets.py.expect similarity index 92% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/return_annotation_brackets.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/return_annotation_brackets.py.expect index 06880ecbe0bde..c8a8ce2ca29f7 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/return_annotation_brackets.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/return_annotation_brackets.py.expect @@ -118,3 +118,11 @@ def foo() -> ( ] ): return 2 + + +# Magic trailing comma example, with params +# this is broken - the trailing comma is transferred to the param list. Fixed in preview +def foo( + a, b +) -> tuple[int, int, int,]: + return 2 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/skip_magic_trailing_comma.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/skip_magic_trailing_comma.options.json new file mode 100644 index 0000000000000..cbb67df0c6676 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/skip_magic_trailing_comma.options.json @@ -0,0 +1 @@ +{"magic_trailing_comma": "ignore"} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/skip_magic_trailing_comma.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/skip_magic_trailing_comma.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/skip_magic_trailing_comma.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/skip_magic_trailing_comma.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/skip_magic_trailing_comma.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/skip_magic_trailing_comma.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/skip_magic_trailing_comma.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/skip_magic_trailing_comma.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/slices.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/slices.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/slices.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/slices.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/slices.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/slices.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/slices.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/slices.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/starred_for_target.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/starred_for_target.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/starred_for_target.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/starred_for_target.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_310/starred_for_target.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/starred_for_target.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_310/starred_for_target.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/starred_for_target.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/string_prefixes.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/string_prefixes.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/string_prefixes.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/string_prefixes.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/string_prefixes.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/string_prefixes.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/string_prefixes.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/string_prefixes.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/stub.pyi b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/stub.pyi new file mode 100644 index 0000000000000..d3ad0ca1dd6f6 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/stub.pyi @@ -0,0 +1,75 @@ +X: int + +def f(): ... + + +class D: + ... + + +class C: + ... + +class B: + this_lack_of_newline_should_be_kept: int + def b(self) -> None: ... + + but_this_newline_should_also_be_kept: int + +class A: + attr: int + attr2: str + + def f(self) -> int: + ... + + def g(self) -> str: ... + + + +def g(): + ... + +def h(): ... + +if sys.version_info >= (3, 8): + class E: + def f(self): ... + class F: + + def f(self): ... + class G: ... + class H: ... +else: + class I: ... + class J: ... + def f(): ... + + class K: + def f(self): ... + def f(): ... + +class Nested: + class dirty: ... + class little: ... + class secret: + def who_has_to_know(self): ... + def verse(self): ... + +class Conditional: + def f(self): ... + if sys.version_info >= (3, 8): + def g(self): ... + else: + def g(self): ... + def h(self): ... + def i(self): ... + if sys.version_info >= (3, 8): + def j(self): ... + def k(self): ... + if sys.version_info >= (3, 8): + class A: ... + class B: ... + class C: + def l(self): ... + def m(self): ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/cases/stub.pyi.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/stub.pyi.expect new file mode 100644 index 0000000000000..5a7ab3a03351f --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/stub.pyi.expect @@ -0,0 +1,73 @@ +X: int + +def f(): ... + +class D: ... +class C: ... + +class B: + this_lack_of_newline_should_be_kept: int + def b(self) -> None: ... + + but_this_newline_should_also_be_kept: int + +class A: + attr: int + attr2: str + + def f(self) -> int: ... + def g(self) -> str: ... + +def g(): ... +def h(): ... + +if sys.version_info >= (3, 8): + class E: + def f(self): ... + + class F: + def f(self): ... + + class G: ... + class H: ... + +else: + class I: ... + class J: ... + + def f(): ... + + class K: + def f(self): ... + + def f(): ... + +class Nested: + class dirty: ... + class little: ... + + class secret: + def who_has_to_know(self): ... + + def verse(self): ... + +class Conditional: + def f(self): ... + if sys.version_info >= (3, 8): + def g(self): ... + else: + def g(self): ... + + def h(self): ... + def i(self): ... + if sys.version_info >= (3, 8): + def j(self): ... + + def k(self): ... + if sys.version_info >= (3, 8): + class A: ... + class B: ... + + class C: + def l(self): ... + def m(self): ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/torture.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/torture.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/torture.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/torture.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/torture.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/torture.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/torture.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/torture.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens1.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens1.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens1.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens1.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens1.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens1.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens1.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens1.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens2.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens2.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens2.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens2.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens2.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens2.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens2.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens2.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens3.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens3.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens3.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens3.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens3.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens3.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_comma_optional_parens3.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_comma_optional_parens3.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_commas_in_leading_parts.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_commas_in_leading_parts.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_commas_in_leading_parts.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_commas_in_leading_parts.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_commas_in_leading_parts.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_commas_in_leading_parts.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_commas_in_leading_parts.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_commas_in_leading_parts.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tricky_unicode_symbols.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/tricky_unicode_symbols.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tricky_unicode_symbols.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/tricky_unicode_symbols.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tricky_unicode_symbols.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/tricky_unicode_symbols.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tricky_unicode_symbols.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/tricky_unicode_symbols.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tupleassign.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/tupleassign.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tupleassign.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/tupleassign.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tupleassign.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/tupleassign.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tupleassign.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/tupleassign.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/type_comments/type_comment_syntax_error.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/type_comment_syntax_error.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/type_comments/type_comment_syntax_error.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/type_comment_syntax_error.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/type_comments/type_comment_syntax_error.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/type_comment_syntax_error.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/type_comments/type_comment_syntax_error.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/type_comment_syntax_error.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_params.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/type_params.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_params.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/type_params.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_params.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/type_params.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_params.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/type_params.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/whitespace.py b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/whitespace.py similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/whitespace.py rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/whitespace.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/whitespace.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/cases/whitespace.py.expect similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/whitespace.py.expect rename to crates/ruff_python_formatter/resources/test/fixtures/black/cases/whitespace.py.expect diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/decorators.py b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/decorators.py deleted file mode 100644 index 46e37f69edcb8..0000000000000 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/decorators.py +++ /dev/null @@ -1,150 +0,0 @@ -# This file doesn't use the standard decomposition. -# Decorator syntax test cases are separated by double # comments. -# Those before the 'output' comment are valid under the old syntax. -# Those after the 'ouput' comment require PEP614 relaxed syntax. -# Do not remove the double # separator before the first test case, it allows -# the comment before the test case to be ignored. - -## - -@decorator -def f(): - ... - -## - -@decorator() -def f(): - ... - -## - -@decorator(arg) -def f(): - ... - -## - -@decorator(kwarg=0) -def f(): - ... - -## - -@decorator(*args) -def f(): - ... - -## - -@decorator(**kwargs) -def f(): - ... - -## - -@decorator(*args, **kwargs) -def f(): - ... - -## - -@decorator(*args, **kwargs,) -def f(): - ... - -## - -@dotted.decorator -def f(): - ... - -## - -@dotted.decorator(arg) -def f(): - ... - -## - -@dotted.decorator(kwarg=0) -def f(): - ... - -## - -@dotted.decorator(*args) -def f(): - ... - -## - -@dotted.decorator(**kwargs) -def f(): - ... - -## - -@dotted.decorator(*args, **kwargs) -def f(): - ... - -## - -@dotted.decorator(*args, **kwargs,) -def f(): - ... - -## - -@double.dotted.decorator -def f(): - ... - -## - -@double.dotted.decorator(arg) -def f(): - ... - -## - -@double.dotted.decorator(kwarg=0) -def f(): - ... - -## - -@double.dotted.decorator(*args) -def f(): - ... - -## - -@double.dotted.decorator(**kwargs) -def f(): - ... - -## - -@double.dotted.decorator(*args, **kwargs) -def f(): - ... - -## - -@double.dotted.decorator(*args, **kwargs,) -def f(): - ... - -## - -@_(sequence["decorator"]) -def f(): - ... - -## - -@eval("sequence['decorator']") -def f(): - ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/decorators.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/decorators.py.expect deleted file mode 100644 index df17e1e749f3d..0000000000000 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/decorators.py.expect +++ /dev/null @@ -1,29 +0,0 @@ -## - -@decorator()() -def f(): - ... - -## - -@(decorator) -def f(): - ... - -## - -@sequence["decorator"] -def f(): - ... - -## - -@decorator[List[str]] -def f(): - ... - -## - -@var := decorator -def f(): - ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py index edc7495e66308..9c8c40cc96239 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py @@ -1,4 +1,3 @@ -# flags: --pyi from typing import Union @bird diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.pyi b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.pyi new file mode 100644 index 0000000000000..9c8c40cc96239 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.pyi @@ -0,0 +1,30 @@ +from typing import Union + +@bird +def zoo(): ... + +class A: ... +@bar +class B: + def BMethod(self) -> None: ... + @overload + def BMethod(self, arg : List[str]) -> None: ... + +class C: ... +@hmm +class D: ... +class E: ... + +@baz +def foo() -> None: + ... + +class F (A , C): ... +def spam() -> None: ... + +@overload +def spam(arg: str) -> str: ... + +var : int = 1 + +def eggs() -> Union[str, int]: ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.pyi.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.pyi.expect new file mode 100644 index 0000000000000..4349ba0a53b5b --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.pyi.expect @@ -0,0 +1,32 @@ +from typing import Union + +@bird +def zoo(): ... + +class A: ... + +@bar +class B: + def BMethod(self) -> None: ... + @overload + def BMethod(self, arg: List[str]) -> None: ... + +class C: ... + +@hmm +class D: ... + +class E: ... + +@baz +def foo() -> None: ... + +class F(A, C): ... + +def spam() -> None: ... +@overload +def spam(arg: str) -> str: ... + +var: int = 1 + +def eggs() -> Union[str, int]: ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_aliases.py b/crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_aliases.py deleted file mode 100644 index cdac8402f41e9..0000000000000 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_aliases.py +++ /dev/null @@ -1,5 +0,0 @@ -type A=int -type Gen[T]=list[T] - -type = aliased -print(type(42)) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_aliases.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_aliases.py.expect deleted file mode 100644 index 308a164e198b6..0000000000000 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_aliases.py.expect +++ /dev/null @@ -1,5 +0,0 @@ -type A = int -type Gen[T] = list[T] - -type = aliased -print(type(42)) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.options.json deleted file mode 100644 index f709c8d714b52..0000000000000 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "indent_width": 4 -} diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.options.json new file mode 100644 index 0000000000000..c106a9c8f36ea --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.options.json @@ -0,0 +1,3 @@ +{ + "preview": "enabled" +} diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.py b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.py new file mode 100644 index 0000000000000..eff37f23c008b --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.py @@ -0,0 +1,141 @@ +def foo_brackets(request): + return JsonResponse( + { + "var_1": foo, + "var_2": bar, + } + ) + +def foo_square_brackets(request): + return JsonResponse( + [ + "var_1", + "var_2", + ] + ) + +func({"a": 37, "b": 42, "c": 927, "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111}) + +func(["random_string_number_one","random_string_number_two","random_string_number_three","random_string_number_four"]) + +func( + { + # expand me + 'a':37, + 'b':42, + 'c':927 + } +) + +func( + [ + 'a', + 'b', + 'c', + ] +) + +func( + [ + 'a', + 'b', + 'c', + ], +) + +func( # a + [ # b + "c", # c + "d", # d + "e", # e + ] # f +) # g + +func( # a + { # b + "c": 1, # c + "d": 2, # d + "e": 3, # e + } # f +) # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func( + [ # preserve me but hug brackets + "c", + "d", + "e", + ] +) + +func( + [ + # preserve me but hug brackets + "c", + "d", + "e", + ] +) + +func( + [ + "c", + # preserve me but hug brackets + "d", + "e", + ] +) + +func( + [ + "c", + "d", + "e", + # preserve me but hug brackets + ] +) + +func( + [ + "c", + "d", + "e", + ] # preserve me but hug brackets +) + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func([x for x in "long line long line long line long line long line long line long line"]) +func([x for x in [x for x in "long line long line long line long line long line long line long line"]]) + +func({"short line"}) +func({"long line", "long long line", "long long long line", "long long long long line", "long long long long long line"}) +func({{"long line", "long long line", "long long long line", "long long long long line", "long long long long long line"}}) + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +foo(*["long long long long long line", "long long long long long line", "long long long long long line"]) + +foo(*[str(i) for i in range(100000000000000000000000000000000000000000000000000000000000)]) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.py.expect new file mode 100644 index 0000000000000..963fb7c4040a4 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.py.expect @@ -0,0 +1,159 @@ +def foo_brackets(request): + return JsonResponse({ + "var_1": foo, + "var_2": bar, + }) + + +def foo_square_brackets(request): + return JsonResponse([ + "var_1", + "var_2", + ]) + + +func({ + "a": 37, + "b": 42, + "c": 927, + "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111, +}) + +func([ + "random_string_number_one", + "random_string_number_two", + "random_string_number_three", + "random_string_number_four", +]) + +func({ + # expand me + "a": 37, + "b": 42, + "c": 927, +}) + +func([ + "a", + "b", + "c", +]) + +func( + [ + "a", + "b", + "c", + ], +) + +func([ # a # b + "c", # c + "d", # d + "e", # e +]) # f # g + +func({ # a # b + "c": 1, # c + "d": 2, # d + "e": 3, # e +}) # f # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func([ # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + "c", + # preserve me but hug brackets + "d", + "e", +]) + +func([ + "c", + "d", + "e", + # preserve me but hug brackets +]) + +func([ + "c", + "d", + "e", +]) # preserve me but hug brackets + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func([ + x for x in "long line long line long line long line long line long line long line" +]) +func([ + x + for x in [ + x + for x in "long line long line long line long line long line long line long line" + ] +]) + +func({"short line"}) +func({ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +}) +func({ + { + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", + } +}) + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +foo(*[ + "long long long long long line", + "long long long long long line", + "long long long long long line", +]) + +foo(*[ + str(i) for i in range(100000000000000000000000000000000000000000000000000000000000) +]) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/skip_magic_trailing_comma.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/skip_magic_trailing_comma.options.json deleted file mode 100644 index e01e786cb6376..0000000000000 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/skip_magic_trailing_comma.options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "magic_trailing_comma": "ignore" -} \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/import_black_tests.py b/crates/ruff_python_formatter/resources/test/fixtures/import_black_tests.py index ad45c017847d7..b196876e7063e 100755 --- a/crates/ruff_python_formatter/resources/test/fixtures/import_black_tests.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/import_black_tests.py @@ -3,6 +3,8 @@ from __future__ import annotations import argparse +import json +import os from pathlib import Path @@ -14,22 +16,18 @@ def import_fixture(fixture: Path, fixture_set: str): output_directory = Path(__file__).parent.joinpath("black").joinpath(fixture_set) output_directory.mkdir(parents=True, exist_ok=True) - fixture_path = output_directory.joinpath(fixture.name) - expect_path = fixture_path.with_suffix(".py.expect") - - with ( - fixture.open("r") as black_file, - fixture_path.open("w") as fixture_file, - expect_path.open("w") as expect_file - ): + with fixture.open("r") as black_file: lines = iter(black_file) expected = [] input = [] + flags = None for line in lines: if line.rstrip() == "# output": expected = list(lines) break + elif not input and line.startswith("# flags:"): + flags = line else: input.append(line) @@ -37,24 +35,47 @@ def import_fixture(fixture: Path, fixture_set: str): # If there's no output marker, tread the whole file as already pre-formatted expected = input - fixture_file.write("".join(input).strip() + "\n") - expect_file.write("".join(expected).strip() + "\n") + options = {} + extension = "py" + + if flags: + if "--preview" in flags: + options["preview"] = "enabled" + + if "--pyi" in flags: + extension = "pyi" + + if "--line-length=" in flags: + [_, length_and_rest] = flags.split("--line-length=", 1) + length = length_and_rest.split(" ", 1)[0] + length = int(length) + options["line_width"] = 1 if length == 0 else length + + if "--skip-magic-trailing-comma" in flags: + options["magic_trailing_comma"] = "ignore" + + fixture_path = output_directory.joinpath(fixture.name).with_suffix(f".{extension}") + expect_path = fixture_path.with_suffix(f".{extension}.expect") + options_path = fixture_path.with_suffix(".options.json") + + if len(options) > 0: + with options_path.open("w") as options_file: + json.dump(options, options_file) + elif os.path.exists(options_path): + os.remove(options_path) + + with ( + fixture_path.open("w") as fixture_file, + expect_path.open("w") as expect_file + ): + fixture_file.write("".join(input).strip() + "\n") + expect_file.write("".join(expected).strip() + "\n") # The name of the folders in the `data` for which the tests should be imported FIXTURE_SETS = [ - "fast", - "py_36", - "py_37", - "py_38", - "py_39", - "py_310", - "py_311", - "py_312", - "simple_cases", + "cases", "miscellaneous", - ".", - "type_comments" ] # Tests that ruff doesn't fully support yet and, therefore, should not be imported @@ -63,9 +84,16 @@ def import_fixture(fixture: Path, fixture_set: str): "async_as_identifier.py", "invalid_header.py", "pattern_matching_invalid.py", + "pep_572_do_not_remove_parens.py", # Python 2 - "python2_detection.py" + "python2_detection.py", + + # Uses a different output format + "decorators.py", + + # Ruff fails to parse because of a parser bug + "type_aliases.py" # #8900 #8899 ] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json index 28553e727b70f..e1a76386a0556 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json @@ -14,5 +14,8 @@ { "indent_style": "tab", "indent_width": 4 + }, + { + "quote_style": "single" } ] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py index d7d4d9b119b17..98a5a730f44f6 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py @@ -150,3 +150,8 @@ def tabbed_indent(self): Normal indented line - autor """ + + +def single_quoted(): + ' content\ ' + return diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples.options.json new file mode 100644 index 0000000000000..9400ae4bea230 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples.options.json @@ -0,0 +1,54 @@ +[ + { + "docstring_code": "disabled", + "indent_style": "space", + "indent_width": 4 + }, + { + "docstring_code": "disabled", + "indent_style": "space", + "indent_width": 2 + }, + { + "docstring_code": "disabled", + "indent_style": "tab", + "indent_width": 8 + }, + { + "docstring_code": "disabled", + "indent_style": "tab", + "indent_width": 4 + }, + { + "docstring_code": "enabled", + "indent_style": "space", + "indent_width": 4 + }, + { + "docstring_code": "enabled", + "indent_style": "space", + "indent_width": 2 + }, + { + "docstring_code": "enabled", + "indent_style": "tab", + "indent_width": 8 + }, + { + "docstring_code": "enabled", + "indent_style": "tab", + "indent_width": 4 + }, + { + "docstring_code": "enabled", + "docstring_code_line_width": 60, + "indent_style": "space", + "indent_width": 4 + }, + { + "docstring_code": "enabled", + "docstring_code_line_width": "dynamic", + "indent_style": "space", + "indent_width": 4 + } +] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples.py new file mode 100644 index 0000000000000..381f04b757adf --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples.py @@ -0,0 +1,1350 @@ +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + >>> cool_stuff( y ) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x )""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + ... more( y )""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... + ... print( x ) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested( x ): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + ''' + Do cool stuff. + + >>> assert ("Easy!") + >>> import math + >>> math.floor( 1.9 ) + 1 + ''' + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + ''' + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard) + ''' + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( x ) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff( 1 )""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff( 1 ) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff( 1 ) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff( 1 ) + cool_stuff( 2 ) + cool_stuff( 3 ) + cool_stuff( 4 ) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff( x ): + print( f"hi {x}" ); + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff( 1 ) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ```invalid + ''' + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( ''' + ``` + did i trick you? + ``` + ''' ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + + + """ + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 )""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + + + cool_stuff( 1 ) + + + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff( 1 ) + + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print( 5 ) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py +cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.options.json new file mode 100644 index 0000000000000..6af4394568536 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.options.json @@ -0,0 +1,8 @@ +[ + { + "docstring_code": "enabled", + "indent_style": "space", + "indent_width": 4, + "line_ending": "CarriageReturnLineFeed" + } +] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py new file mode 100644 index 0000000000000..05cc97963f21e --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py @@ -0,0 +1,9 @@ +def doctest_line_ending(): + """ + Do cool stuff. + >>> def foo( x ): + ... print( x ) + ... + ... print( x ) + """ + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_dynamic_line_width.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_dynamic_line_width.options.json new file mode 100644 index 0000000000000..3367effa0051c --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_dynamic_line_width.options.json @@ -0,0 +1,26 @@ +[ + { + "docstring_code": "enabled", + "docstring_code_line_width": "dynamic", + "indent_style": "space", + "indent_width": 4 + }, + { + "docstring_code": "enabled", + "docstring_code_line_width": "dynamic", + "indent_style": "space", + "indent_width": 2 + }, + { + "docstring_code": "enabled", + "docstring_code_line_width": "dynamic", + "indent_style": "tab", + "indent_width": 4 + }, + { + "docstring_code": "enabled", + "docstring_code_line_width": "dynamic", + "indent_style": "tab", + "indent_width": 8 + } +] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_dynamic_line_width.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_dynamic_line_width.py new file mode 100644 index 0000000000000..e84d3b0707b8b --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_dynamic_line_width.py @@ -0,0 +1,221 @@ +def simple(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + ``` + + Done. + """ + pass + + +# Like simple, but we double everything up to ensure the indent level is +# tracked correctly. +def repeated(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + + class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + ``` + + Done. + """ + pass + + +# Like simple, but we make one line exactly one character longer than the limit +# (for 4-space indents) and make sure it gets wrapped. +def barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678) + return 5 + self.x = doit( 5 ) + ``` + + Done. + """ + pass + + +# This tests that if the code block is unindented, that it gets indented and +# the dynamic line width setting is applied correctly. +def unindented(): + """ + First line. + +```py +class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) +``` + + Done. + """ + pass + + +# Like unindented, but contains a `print` line where it just barely exceeds the +# globally configured line width *after* its indentation has been corrected. +def unindented_barely_exceeds_limit(): + """ + First line. + +```py +class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678) + return 5 + self.x = doit( 5 ) +``` + + Done. + """ + pass + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent1(): + """ + Docstring example containing a class. + + Examples + -------- + >>> @pl.api.register_dataframe_namespace("split") + ... class SplitFrame: + ... def __init__(self, df: pl.DataFrame): + ... self._df = df + ... + ... def by_first_letter_of_column_values(self, col: str) -> list[pl.DataFrame]: + ... return [ + ... self._df.filter(pl.col(col).str.starts_with(c)) + ... for c in sorted( + ... set(df.select(pl.col(col).str.slice(0, 1)).to_series()) + ... ) + ... ] + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +class DoctestExtraIndent2: + def example2(): + """ + Regular docstring of class method. + + Examples + -------- + >>> df = pl.DataFrame( + ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} + ... ) + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent3(): + """ + Pragma comment. + + Examples + -------- + >>> af1, af2, af3 = pl.align_frames( + ... df1, df2, df3, on="dt" + ... ) # doctest: +IGNORE_RESULT + """ diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary.py index 5d91dc500a930..83c6f0ff9fc3a 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary.py @@ -319,6 +319,18 @@ ) ) +# Skip FString content when determining whether to omit optional parentheses or not.0 +# The below expression should be parenthesized because it ends with an fstring and starts with a name. +# (Call expressions at the beginning don't count as parenthesized because they don't start with parens). +assert ( + format.format_event(spec) + == f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})' +) +# Avoid parentheses for this example because it starts with a tuple expression. +assert ( + (spec, format) + == f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})' +) rowuses = [(1 << j) | # column ordinal (1 << (n + i-j + n-1)) | # NW-SE ordinal diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/hug.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/hug.py new file mode 100644 index 0000000000000..bbd41b51a8ba7 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/hug.py @@ -0,0 +1,153 @@ +# Preview style: hug brackets to call parentheses. +func([1, 2, 3,]) + +func( # comment +[1, 2, 3,]) + +func( + # comment +[1, 2, 3,]) + +func([1, 2, 3,] # comment +) + +func([1, 2, 3,] + # comment +) + +func([ # comment + 1, 2, 3,] +) + +func(([1, 2, 3,])) + + +func( + ( + 1, + 2, + 3, + ) +) + +# Ensure that comprehensions hug too. +func([(x, y,) for (x, y) in z]) + +# Ensure that dictionaries hug too. +func({1: 2, 3: 4, 5: 6,}) + +# Ensure that the same behavior is applied to parenthesized expressions. +([1, 2, 3,]) + +( # comment + [1, 2, 3,]) + +( + [ # comment + 1, 2, 3,]) + +# Ensure that starred arguments are also hugged. +foo( + *[ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + * # comment + [ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + **[ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + ** # comment + [ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +# Ensure that multi-argument calls are _not_ hugged. +func([1, 2, 3,], bar) + +func([(x, y,) for (x, y) in z], bar) + +# Ensure that return type annotations (which use `parenthesize_if_expands`) are also hugged. +def func() -> [1, 2, 3,]: + pass + +def func() -> ([1, 2, 3,]): + pass + +def func() -> ([1, 2, 3,]): + pass + +def func() -> ( # comment + [1, 2, 3,]): + pass + +def func() -> ( + [1, 2, 3,] # comment +): + pass + +def func() -> ( + [1, 2, 3,] + # comment +): + pass + +# Ensure that nested lists are hugged. +func([ + [ + 1, + 2, + 3, + ] +]) + + +func([ + # comment + [ + 1, + 2, + 3, + ] +]) + +func([ + [ + 1, + 2, + 3, + ] + # comment +]) + +func([ + [ # comment + 1, + 2, + 3, + ] +]) + + +func([ # comment + [ + 1, + 2, + 3, + ] +]) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.options.json new file mode 100644 index 0000000000000..59431bf1c4874 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.options.json @@ -0,0 +1,11 @@ +[ + { + "quote_style": "single" + }, + { + "quote_style": "double" + }, + { + "quote_style": "preserve" + } +] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.py new file mode 100644 index 0000000000000..8f0d159bebd4a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.py @@ -0,0 +1,50 @@ +'single' +"double" +r'r single' +r"r double" +f'f single' +f"f double" +fr'fr single' +fr"fr double" +rf'rf single' +rf"rf double" +b'b single' +b"b double" +rb'rb single' +rb"rb double" +br'br single' +br"br double" + +'''single triple''' +"""double triple""" +r'''r single triple''' +r"""r double triple""" +f'''f single triple''' +f"""f double triple""" +fr'''fr single triple''' +fr"""fr double triple""" +rf'''rf single triple''' +rf"""rf double triple""" +b'''b single triple''' +b"""b double triple""" +rb'''rb single triple''' +rb"""rb double triple""" +br'''br single triple''' +br"""br double triple""" + +'single1' 'single2' +'single1' "double2" +"double1" 'single2' +"double1" "double2" + +def docstring_single_triple(): + '''single triple''' + +def docstring_double_triple(): + """double triple""" + +def docstring_double(): + "double triple" + +def docstring_single(): + 'single' diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign.py index 36022ddd7f979..e70ab7c9a604a 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign.py @@ -67,3 +67,12 @@ def main() -> None: db_request.POST["name"] ) )[0] + + +c = b[dddddd, aaaaaa] = ( + a[ + aaaaaaa, + bbbbbbbbbbbbbbbbbbb + ] + # comment +) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assignment_split_value_first.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assignment_split_value_first.options.json new file mode 100644 index 0000000000000..8925dd0a8280f --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assignment_split_value_first.options.json @@ -0,0 +1,5 @@ +[ + { + "preview": "enabled" + } +] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assignment_split_value_first.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assignment_split_value_first.py new file mode 100644 index 0000000000000..4c266a1ad50ee --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assignment_split_value_first.py @@ -0,0 +1,218 @@ +####### +# Unsplittable target and value + +# Only parenthesize the value if it makes it fit, otherwise avoid parentheses. +b = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee + +bbbbbbbbbbbbbbbb = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvv + +# Avoid parenthesizing the value even if the target exceeds the configured width +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = bbb + + +############ +# Splittable targets + +# Does not double-parenthesize tuples +( + first_item, + second_item, +) = some_looooooooong_module.some_loooooog_function_name( + first_argument, second_argument, third_argument +) + + +# Preserve parentheses around the first target +( + req["ticket"]["steps"]["step"][0]["tasks"]["task"]["fields"]["field"][ + "access_request" + ]["destinations"]["destination"][0]["ip_address"] +) = dst + +# Augmented assignment +req["ticket"]["steps"]["step"][0]["tasks"]["task"]["fields"]["field"][ + "access_request" +] += dst + +# Always parenthesize the value if it avoids splitting the target, regardless of the value's width. +_a: a[aaaa] = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv +) + +##### +# Avoid parenthesizing the value if the expression right before the `=` splits to avoid an unnecessary pair of parentheses + +# The type annotation is guaranteed to split because it is too long. +_a: a[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv +] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv + +# The target is too long +( + aaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv + +# The target splits because of a magic trailing comma +( + a, + b, +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +# The targets split because of a comment +( + # leading + a +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +( + a + # trailing +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +( + a, # nested + b +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +####### +# Multi targets + +# Black always parenthesizes the right if using multiple targets regardless if the parenthesized value exceeds the +# the configured line width or not +aaaa = bbbbbbbbbbbbbbbb = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee +) + +# Black does parenthesize the target if the target itself exceeds the line width and only parenthesizes +# the values if it makes it fit. +# The second target is too long to ever fit into the configured line width. +aaaa = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddd +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee + +# Does also apply for other multi target assignments, as soon as a single target exceeds the configured +# width +aaaaaa = a["aaa"] = bbbbb[aa, bbb, cccc] = dddddddddd = eeeeee = ( + fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + +###################### +# Call expressions: +# For unsplittable targets: Parenthesize the call expression if it makes it fit. +# +# For splittable targets: +# Only parenthesize a call expression if the parens of the call don't fit on the same line +# as the target. Don't parenthesize the call expression if the target (or annotation) right before +# splits. + +# Don't parenthesize the function call if the left is unsplittable. +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = a.b.function( + arg1, arg2, arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], + arg1, + [1, 2, 3], + arg2, + [1, 2, 3], + arg3, + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd, + eeeeeeeeeeeeee, +) + +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( + function() +) +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = ( + a.b.function(arg1, arg2, arg3) +) +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function() +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function( + [1, 2, 3], + arg1, + [1, 2, 3], + arg2, + [1, 2, 3], + arg3, + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd, + eeeeeeeeeeeeee, +) + +####### Fluent call expressions +# Uses the regular `Multiline` layout where the entire `value` gets parenthesized +# if it doesn't fit on the line. +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use = ( + function().b().c([1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3) +) + + +####### +# Test comment inlining +value.__dict__[key] = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) +value.__dict__.keye = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) +value.__dict__.keye = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) + + +# Don't parenthesize the value because the target's trailing comma forces it to split. +a[ + aaaaaaa, + b, +] = cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc # comment + +# Parenthesize the value, but don't duplicate the comment. +a[aaaaaaa, b] = ( + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc # comment +) + +# Format both as flat, but don't loos the comment. +a[aaaaaaa, b] = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb # comment + +####################################################### +# Test the case where a parenthesized value now fits: +a[ + aaaaaaa, + b +] = ( + cccccccc # comment +) + +# Splits the target but not the value because of the magic trailing comma. +a[ + aaaaaaa, + b, +] = ( + cccccccc # comment +) + +# Splits the second target because of the comment and the first target because of the trailing comma. +a[ + aaaaaaa, + b, +] = ( + # leading comment + b +) = ( + cccccccc # comment +) + + +######## +# Type Alias Statement +type A[str, int, number] = VeryLongTypeNameThatShouldBreakFirstToTheRightBeforeSplitngtin + +type A[VeryLongTypeNameThatShouldBreakFirstToTheRightBeforeSplitngtinthatExceedsTheWidth] = str + diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ellipsis.pyi b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ellipsis.pyi index 499ef0aacc0c7..aa693c3443edd 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ellipsis.pyi +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ellipsis.pyi @@ -68,6 +68,10 @@ with True: with True: ... # comment +with True: + ... + # comment + match x: case 1: ... @@ -99,4 +103,4 @@ try: except: ... # comment finally: - ... # comment \ No newline at end of file + ... # comment diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py index 98eb09eefafcb..20eca870395fd 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py @@ -410,3 +410,13 @@ def default_arg_comments2(# # ): print(x) + +def function_with_one_argument_and_a_positional_separator( + argument: str, / +) -> ReallyReallyReallyReallyReallyReallyReallyReallyLongName: + pass + +def function_with_one_argument_and_a_keyword_separator( + *, argument: str +) -> ReallyReallyReallyReallyReallyReallyReallyReallyLongName: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/match.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/match.py index 3d9855a154738..f24f9416cc0ef 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/match.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/match.py @@ -578,3 +578,8 @@ def foo(): print("Buzz") case _: print(n) + +# Unparenthesized tuples +match x: + case Child(aaaaaaaaa, bbbbbbbbbbbbbbb, cccccc), Doc(aaaaa, bbbbbbbbbb, ddddddddddddd): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py index 8e29cd3730c9c..ad13b9d84cd6e 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py @@ -16,10 +16,12 @@ type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[Aaaaaaaaaaaaaaaaaaaaaaaaaaaa] = int type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[Aaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbb] = int type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = Tttttttttttttttttttttttttttttttttttttttttttttttttttttttt +type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = Tttttttttttttttttttttttttttttttttttttttttttttttttttttttt # with comment # long value type X = Ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt type X = Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | Ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +type XXXXXXXXXXXXX = Tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt # with comment # soft keyword as alias name type type = int diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py index 4dc166009a363..b222747733fe9 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py @@ -303,3 +303,7 @@ if True: with anyio.CancelScope(shield=True) if get_running_loop() else contextlib.nullcontext(): pass + + +with Child(aaaaaaaaa, bbbbbbbbbbbbbbb, cccccc), Document(aaaaa, bbbbbbbbbb, ddddddddddddd): + pass diff --git a/crates/ruff_python_formatter/src/builders.rs b/crates/ruff_python_formatter/src/builders.rs index 581fdc5194a66..e4e2909a4a6dd 100644 --- a/crates/ruff_python_formatter/src/builders.rs +++ b/crates/ruff_python_formatter/src/builders.rs @@ -1,4 +1,4 @@ -use ruff_formatter::{format_args, write, Argument, Arguments}; +use ruff_formatter::{write, Argument, Arguments}; use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::context::{NodeLevel, WithNodeLevel}; @@ -12,11 +12,20 @@ where { ParenthesizeIfExpands { inner: Argument::new(content), + indent: true, } } pub(crate) struct ParenthesizeIfExpands<'a, 'ast> { inner: Argument<'a, PyFormatContext<'ast>>, + indent: bool, +} + +impl ParenthesizeIfExpands<'_, '_> { + pub(crate) fn with_indent(mut self, indent: bool) -> Self { + self.indent = indent; + self + } } impl<'ast> Format> for ParenthesizeIfExpands<'_, 'ast> { @@ -26,11 +35,17 @@ impl<'ast> Format> for ParenthesizeIfExpands<'_, 'ast> { write!( f, - [group(&format_args![ - if_group_breaks(&token("(")), - soft_block_indent(&Arguments::from(&self.inner)), - if_group_breaks(&token(")")), - ])] + [group(&format_with(|f| { + if_group_breaks(&token("(")).fmt(f)?; + + if self.indent { + soft_block_indent(&Arguments::from(&self.inner)).fmt(f)?; + } else { + Arguments::from(&self.inner).fmt(f)?; + }; + + if_group_breaks(&token(")")).fmt(f) + }))] ) } } diff --git a/crates/ruff_python_formatter/src/comments/map.rs b/crates/ruff_python_formatter/src/comments/map.rs index 7ef01dc736c7f..2e5846c85a410 100644 --- a/crates/ruff_python_formatter/src/comments/map.rs +++ b/crates/ruff_python_formatter/src/comments/map.rs @@ -539,11 +539,11 @@ struct PartIndex(NonZeroU32); impl PartIndex { fn from_len(value: usize) -> Self { assert!(value < u32::MAX as usize); - // SAFETY: + // OK because: // * The `value < u32::MAX` guarantees that the add doesn't overflow. // * The `+ 1` guarantees that the index is not zero - #[allow(unsafe_code, clippy::cast_possible_truncation)] - Self(unsafe { std::num::NonZeroU32::new_unchecked((value as u32) + 1) }) + #[allow(clippy::cast_possible_truncation)] + Self(std::num::NonZeroU32::new((value as u32) + 1).expect("valid value")) } fn value(self) -> usize { diff --git a/crates/ruff_python_formatter/src/comments/placement.rs b/crates/ruff_python_formatter/src/comments/placement.rs index 5fe12bd190322..4b667fd23629f 100644 --- a/crates/ruff_python_formatter/src/comments/placement.rs +++ b/crates/ruff_python_formatter/src/comments/placement.rs @@ -283,13 +283,13 @@ fn handle_enclosed_comment<'a>( AnyNodeRef::StmtWith(with_) => handle_with_comment(comment, with_), AnyNodeRef::ExprCall(_) => handle_call_comment(comment), AnyNodeRef::ExprStringLiteral(_) => { - if let Some(AnyNodeRef::ExprFString(fstring)) = comment.enclosing_parent() { + if let Some(AnyNodeRef::FString(fstring)) = comment.enclosing_parent() { CommentPlacement::dangling(fstring, comment) } else { CommentPlacement::Default(comment) } } - AnyNodeRef::ExprFString(fstring) => CommentPlacement::dangling(fstring, comment), + AnyNodeRef::FString(fstring) => CommentPlacement::dangling(fstring, comment), AnyNodeRef::ExprList(_) | AnyNodeRef::ExprSet(_) | AnyNodeRef::ExprListComp(_) diff --git a/crates/ruff_python_formatter/src/context.rs b/crates/ruff_python_formatter/src/context.rs index f92825fe958f4..b5dc85fcb3039 100644 --- a/crates/ruff_python_formatter/src/context.rs +++ b/crates/ruff_python_formatter/src/context.rs @@ -1,6 +1,7 @@ use crate::comments::Comments; +use crate::string::QuoteChar; use crate::PyFormatOptions; -use ruff_formatter::{Buffer, FormatContext, GroupId, SourceCode}; +use ruff_formatter::{Buffer, FormatContext, GroupId, IndentWidth, SourceCode}; use ruff_source_file::Locator; use std::fmt::{Debug, Formatter}; use std::ops::{Deref, DerefMut}; @@ -11,6 +12,16 @@ pub struct PyFormatContext<'a> { contents: &'a str, comments: Comments<'a>, node_level: NodeLevel, + indent_level: IndentLevel, + /// Set to a non-None value when the formatter is running on a code + /// snippet within a docstring. The value should be the quote character of the + /// docstring containing the code snippet. + /// + /// Various parts of the formatter may inspect this state to change how it + /// works. For example, multi-line strings will always be written with a + /// quote style that is inverted from the one here in order to ensure that + /// the formatted Python code will be valid. + docstring: Option, } impl<'a> PyFormatContext<'a> { @@ -20,6 +31,8 @@ impl<'a> PyFormatContext<'a> { contents, comments, node_level: NodeLevel::TopLevel(TopLevelStatementPosition::Other), + indent_level: IndentLevel::new(0), + docstring: None, } } @@ -40,9 +53,43 @@ impl<'a> PyFormatContext<'a> { self.node_level } + pub(crate) fn set_indent_level(&mut self, level: IndentLevel) { + self.indent_level = level; + } + + pub(crate) fn indent_level(&self) -> IndentLevel { + self.indent_level + } + pub(crate) fn comments(&self) -> &Comments<'a> { &self.comments } + + /// Returns a non-None value only if the formatter is running on a code + /// snippet within a docstring. + /// + /// The quote character returned corresponds to the quoting used for the + /// docstring containing the code snippet currently being formatted. + pub(crate) fn docstring(&self) -> Option { + self.docstring + } + + /// Return a new context suitable for formatting code snippets within a + /// docstring. + /// + /// The quote character given should correspond to the quote character used + /// for the docstring containing the code snippets. + pub(crate) fn in_docstring(self, quote: QuoteChar) -> PyFormatContext<'a> { + PyFormatContext { + docstring: Some(quote), + ..self + } + } + + /// Returns `true` if preview mode is enabled. + pub(crate) const fn is_preview(&self) -> bool { + self.options.preview().is_enabled() + } } impl FormatContext for PyFormatContext<'_> { @@ -173,3 +220,115 @@ where .set_node_level(self.saved_level); } } + +/// The current indent level of the formatter. +/// +/// One can determine the the width of the indent itself (in number of ASCII +/// space characters) by multiplying the indent level by the configured indent +/// width. +/// +/// This is specifically used inside the docstring code formatter for +/// implementing its "dynamic" line width mode. Namely, in the nested call to +/// the formatter, when "dynamic" mode is enabled, the line width is set to +/// `min(1, line_width - indent_level * indent_width)`, where `line_width` in +/// this context is the global line width setting. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub(crate) struct IndentLevel { + /// The numeric level. It is incremented for every whole indent in Python + /// source code. + /// + /// Note that the first indentation level is actually 1, since this starts + /// at 0 and is incremented when the first top-level statement is seen. So + /// even though the first top-level statement in Python source will have no + /// indentation, its indentation level is 1. + level: u16, +} + +impl IndentLevel { + /// Returns a new indent level for the given value. + pub(crate) fn new(level: u16) -> IndentLevel { + IndentLevel { level } + } + + /// Returns the next indent level. + pub(crate) fn increment(self) -> IndentLevel { + IndentLevel { + level: self.level.saturating_add(1), + } + } + + /// Convert this indent level into a specific number of ASCII whitespace + /// characters based on the given indent width. + pub(crate) fn to_ascii_spaces(self, width: IndentWidth) -> u16 { + let width = u16::try_from(width.value()).unwrap_or(u16::MAX); + // Why the subtraction? IndentLevel starts at 0 and asks for the "next" + // indent level before seeing the first top-level statement. So it's + // always 1 more than what we expect it to be. + let level = self.level.saturating_sub(1); + width.saturating_mul(level) + } +} + +/// Change the [`IndentLevel`] of the formatter for the lifetime of this +/// struct. +pub(crate) struct WithIndentLevel<'a, B, D> +where + D: DerefMut, + B: Buffer>, +{ + buffer: D, + saved_level: IndentLevel, +} + +impl<'a, B, D> WithIndentLevel<'a, B, D> +where + D: DerefMut, + B: Buffer>, +{ + pub(crate) fn new(level: IndentLevel, mut buffer: D) -> Self { + let context = buffer.state_mut().context_mut(); + let saved_level = context.indent_level(); + + context.set_indent_level(level); + + Self { + buffer, + saved_level, + } + } +} + +impl<'a, B, D> Deref for WithIndentLevel<'a, B, D> +where + D: DerefMut, + B: Buffer>, +{ + type Target = B; + + fn deref(&self) -> &Self::Target { + &self.buffer + } +} + +impl<'a, B, D> DerefMut for WithIndentLevel<'a, B, D> +where + D: DerefMut, + B: Buffer>, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.buffer + } +} + +impl<'a, B, D> Drop for WithIndentLevel<'a, B, D> +where + D: DerefMut, + B: Buffer>, +{ + fn drop(&mut self) { + self.buffer + .state_mut() + .context_mut() + .set_indent_level(self.saved_level); + } +} diff --git a/crates/ruff_python_formatter/src/expression/binary_like.rs b/crates/ruff_python_formatter/src/expression/binary_like.rs index f77851e395cb5..3e153ad8c2358 100644 --- a/crates/ruff_python_formatter/src/expression/binary_like.rs +++ b/crates/ruff_python_formatter/src/expression/binary_like.rs @@ -13,14 +13,15 @@ use ruff_text_size::{Ranged, TextRange}; use crate::comments::{leading_comments, trailing_comments, Comments, SourceComment}; use crate::expression::parentheses::{ - in_parentheses_only_group, in_parentheses_only_soft_line_break, - in_parentheses_only_soft_line_break_or_space, is_expression_parenthesized, - write_in_parentheses_only_group_end_tag, write_in_parentheses_only_group_start_tag, - Parentheses, + in_parentheses_only_group, in_parentheses_only_if_group_breaks, + in_parentheses_only_soft_line_break, in_parentheses_only_soft_line_break_or_space, + is_expression_parenthesized, write_in_parentheses_only_group_end_tag, + write_in_parentheses_only_group_start_tag, Parentheses, }; -use crate::expression::string::{AnyString, FormatString, StringLayout}; use crate::expression::OperatorPrecedence; use crate::prelude::*; +use crate::preview::is_fix_power_op_line_length_enabled; +use crate::string::{AnyString, FormatStringContinuation}; #[derive(Copy, Clone, Debug)] pub(super) enum BinaryLike<'a> { @@ -394,9 +395,10 @@ impl Format> for BinaryLike<'_> { [ operand.leading_binary_comments().map(leading_comments), leading_comments(comments.leading(&string_constant)), - FormatString::new(&string_constant).with_layout( - StringLayout::ImplicitConcatenatedStringInBinaryLike, - ), + // Call `FormatStringContinuation` directly to avoid formatting + // the implicitly concatenated string with the enclosing group + // because the group is added by the binary like formatting. + FormatStringContinuation::new(&string_constant), trailing_comments(comments.trailing(&string_constant)), operand.trailing_binary_comments().map(trailing_comments), line_suffix_boundary(), @@ -412,9 +414,10 @@ impl Format> for BinaryLike<'_> { f, [ leading_comments(comments.leading(&string_constant)), - FormatString::new(&string_constant).with_layout( - StringLayout::ImplicitConcatenatedStringInBinaryLike - ), + // Call `FormatStringContinuation` directly to avoid formatting + // the implicitly concatenated string with the enclosing group + // because the group is added by the binary like formatting. + FormatStringContinuation::new(&string_constant), trailing_comments(comments.trailing(&string_constant)), ] )?; @@ -718,7 +721,11 @@ impl Format> for FlatBinaryExpressionSlice<'_> { ) { hard_line_break().fmt(f)?; - } else if !is_pow { + } else if is_pow { + if is_fix_power_op_line_length_enabled(f.context()) { + in_parentheses_only_if_group_breaks(&space()).fmt(f)?; + } + } else { space().fmt(f)?; } @@ -1105,9 +1112,8 @@ impl OperatorIndex { fn new(index: usize) -> Self { assert_eq!(index % 2, 1, "Operator indices must be odd positions"); - // SAFETY A value with a module 0 is guaranteed to never equal 0 - #[allow(unsafe_code)] - Self(unsafe { NonZeroUsize::new_unchecked(index) }) + // OK because a value with a modulo 1 is guaranteed to never equal 0 + Self(NonZeroUsize::new(index).expect("valid index")) } const fn value(self) -> usize { diff --git a/crates/ruff_python_formatter/src/expression/expr_bin_op.rs b/crates/ruff_python_formatter/src/expression/expr_bin_op.rs index 4a9361881d7e5..337dd825f2f4f 100644 --- a/crates/ruff_python_formatter/src/expression/expr_bin_op.rs +++ b/crates/ruff_python_formatter/src/expression/expr_bin_op.rs @@ -35,13 +35,13 @@ impl NeedsParentheses for ExprBinOp { ) -> OptionalParentheses { if parent.is_expr_await() { OptionalParentheses::Always - } else if self.left.is_literal_expr() { + } else if let Some(literal_expr) = self.left.as_literal_expr() { // Multiline strings are guaranteed to never fit, avoid adding unnecessary parentheses - if !self.left.is_implicit_concatenated_string() - && is_multiline_string(self.left.as_ref().into(), context.source()) + if !literal_expr.is_implicit_concatenated() + && is_multiline_string(literal_expr.into(), context.source()) && has_parentheses(&self.right, context).is_some() && !context.comments().has_dangling(self) - && !context.comments().has(self.left.as_ref()) + && !context.comments().has(literal_expr) && !context.comments().has(self.right.as_ref()) { OptionalParentheses::Never diff --git a/crates/ruff_python_formatter/src/expression/expr_bytes_literal.rs b/crates/ruff_python_formatter/src/expression/expr_bytes_literal.rs index 968487a07cb4a..4869a2d536908 100644 --- a/crates/ruff_python_formatter/src/expression/expr_bytes_literal.rs +++ b/crates/ruff_python_formatter/src/expression/expr_bytes_literal.rs @@ -3,16 +3,24 @@ use ruff_python_ast::ExprBytesLiteral; use crate::comments::SourceComment; use crate::expression::expr_string_literal::is_multiline_string; -use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; -use crate::expression::string::{AnyString, FormatString}; +use crate::expression::parentheses::{ + in_parentheses_only_group, NeedsParentheses, OptionalParentheses, +}; use crate::prelude::*; +use crate::string::{AnyString, FormatStringContinuation}; #[derive(Default)] pub struct FormatExprBytesLiteral; impl FormatNodeRule for FormatExprBytesLiteral { fn fmt_fields(&self, item: &ExprBytesLiteral, f: &mut PyFormatter) -> FormatResult<()> { - FormatString::new(&AnyString::Bytes(item)).fmt(f) + let ExprBytesLiteral { value, .. } = item; + + match value.as_slice() { + [bytes_literal] => bytes_literal.format().fmt(f), + _ => in_parentheses_only_group(&FormatStringContinuation::new(&AnyString::Bytes(item))) + .fmt(f), + } } fn fmt_dangling_comments( @@ -31,7 +39,7 @@ impl NeedsParentheses for ExprBytesLiteral { _parent: AnyNodeRef, context: &PyFormatContext, ) -> OptionalParentheses { - if self.implicit_concatenated { + if self.value.is_implicit_concatenated() { OptionalParentheses::Multiline } else if is_multiline_string(self.into(), context.source()) { OptionalParentheses::Never diff --git a/crates/ruff_python_formatter/src/expression/expr_compare.rs b/crates/ruff_python_formatter/src/expression/expr_compare.rs index f48bd66eccd9c..e9a338075e318 100644 --- a/crates/ruff_python_formatter/src/expression/expr_compare.rs +++ b/crates/ruff_python_formatter/src/expression/expr_compare.rs @@ -37,11 +37,11 @@ impl NeedsParentheses for ExprCompare { ) -> OptionalParentheses { if parent.is_expr_await() { OptionalParentheses::Always - } else if self.left.is_literal_expr() { + } else if let Some(literal_expr) = self.left.as_literal_expr() { // Multiline strings are guaranteed to never fit, avoid adding unnecessary parentheses - if !self.left.is_implicit_concatenated_string() - && is_multiline_string(self.left.as_ref().into(), context.source()) - && !context.comments().has(self.left.as_ref()) + if !literal_expr.is_implicit_concatenated() + && is_multiline_string(literal_expr.into(), context.source()) + && !context.comments().has(literal_expr) && self.comparators.first().is_some_and(|right| { has_parentheses(right, context).is_some() && !context.comments().has(right) }) diff --git a/crates/ruff_python_formatter/src/expression/expr_f_string.rs b/crates/ruff_python_formatter/src/expression/expr_f_string.rs index 51beb4dbb8f4a..8a8ac81d3524e 100644 --- a/crates/ruff_python_formatter/src/expression/expr_f_string.rs +++ b/crates/ruff_python_formatter/src/expression/expr_f_string.rs @@ -1,21 +1,35 @@ use memchr::memchr2; -use crate::comments::SourceComment; -use ruff_formatter::FormatResult; -use ruff_python_ast::AnyNodeRef; -use ruff_python_ast::ExprFString; +use ruff_python_ast::{AnyNodeRef, ExprFString}; +use ruff_source_file::Locator; +use ruff_text_size::Ranged; -use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; +use crate::comments::SourceComment; +use crate::expression::parentheses::{ + in_parentheses_only_group, NeedsParentheses, OptionalParentheses, +}; +use crate::other::f_string_part::FormatFStringPart; use crate::prelude::*; - -use super::string::{AnyString, FormatString}; +use crate::string::{AnyString, FormatStringContinuation, Quoting}; #[derive(Default)] pub struct FormatExprFString; impl FormatNodeRule for FormatExprFString { fn fmt_fields(&self, item: &ExprFString, f: &mut PyFormatter) -> FormatResult<()> { - FormatString::new(&AnyString::FString(item)).fmt(f) + let ExprFString { value, .. } = item; + + match value.as_slice() { + [f_string_part] => FormatFStringPart::new( + f_string_part, + f_string_quoting(item, &f.context().locator()), + ) + .fmt(f), + _ => { + in_parentheses_only_group(&FormatStringContinuation::new(&AnyString::FString(item))) + .fmt(f) + } + } } fn fmt_dangling_comments( @@ -34,7 +48,7 @@ impl NeedsParentheses for ExprFString { _parent: AnyNodeRef, context: &PyFormatContext, ) -> OptionalParentheses { - if self.implicit_concatenated { + if self.value.is_implicit_concatenated() { OptionalParentheses::Multiline } else if memchr2(b'\n', b'\r', context.source()[self.range].as_bytes()).is_none() { OptionalParentheses::BestFit @@ -43,3 +57,28 @@ impl NeedsParentheses for ExprFString { } } } + +pub(crate) fn f_string_quoting(f_string: &ExprFString, locator: &Locator) -> Quoting { + let unprefixed = locator + .slice(f_string.range()) + .trim_start_matches(|c| c != '"' && c != '\''); + let triple_quoted = unprefixed.starts_with(r#"""""#) || unprefixed.starts_with(r"'''"); + + if f_string + .value + .elements() + .filter_map(|element| element.as_expression()) + .any(|expression| { + let string_content = locator.slice(expression.range()); + if triple_quoted { + string_content.contains(r#"""""#) || string_content.contains("'''") + } else { + string_content.contains(['"', '\'']) + } + }) + { + Quoting::Preserve + } else { + Quoting::CanChange + } +} diff --git a/crates/ruff_python_formatter/src/expression/expr_formatted_value.rs b/crates/ruff_python_formatter/src/expression/expr_formatted_value.rs deleted file mode 100644 index a1939891a30a1..0000000000000 --- a/crates/ruff_python_formatter/src/expression/expr_formatted_value.rs +++ /dev/null @@ -1,24 +0,0 @@ -use ruff_python_ast::AnyNodeRef; -use ruff_python_ast::ExprFormattedValue; - -use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; -use crate::prelude::*; - -#[derive(Default)] -pub struct FormatExprFormattedValue; - -impl FormatNodeRule for FormatExprFormattedValue { - fn fmt_fields(&self, _item: &ExprFormattedValue, _f: &mut PyFormatter) -> FormatResult<()> { - unreachable!("Handled inside of `FormatExprFString"); - } -} - -impl NeedsParentheses for ExprFormattedValue { - fn needs_parentheses( - &self, - _parent: AnyNodeRef, - _context: &PyFormatContext, - ) -> OptionalParentheses { - OptionalParentheses::Multiline - } -} diff --git a/crates/ruff_python_formatter/src/expression/expr_string_literal.rs b/crates/ruff_python_formatter/src/expression/expr_string_literal.rs index e6ce374c292fb..442081886d2ca 100644 --- a/crates/ruff_python_formatter/src/expression/expr_string_literal.rs +++ b/crates/ruff_python_formatter/src/expression/expr_string_literal.rs @@ -1,34 +1,66 @@ use ruff_formatter::FormatRuleWithOptions; -use ruff_python_ast::AnyNodeRef; -use ruff_python_ast::ExprStringLiteral; +use ruff_python_ast::{AnyNodeRef, ExprStringLiteral}; use ruff_text_size::{Ranged, TextLen, TextRange}; use crate::comments::SourceComment; -use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; -use crate::expression::string::{ - AnyString, FormatString, StringLayout, StringPrefix, StringQuotes, +use crate::expression::parentheses::{ + in_parentheses_only_group, NeedsParentheses, OptionalParentheses, }; +use crate::other::string_literal::{FormatStringLiteral, StringLiteralKind}; use crate::prelude::*; +use crate::string::{AnyString, FormatStringContinuation, StringPrefix, StringQuotes}; #[derive(Default)] pub struct FormatExprStringLiteral { - layout: StringLayout, + kind: ExprStringLiteralKind, +} + +#[derive(Default, Copy, Clone, Debug)] +pub enum ExprStringLiteralKind { + #[default] + String, + Docstring, +} + +impl ExprStringLiteralKind { + const fn string_literal_kind(self) -> StringLiteralKind { + match self { + ExprStringLiteralKind::String => StringLiteralKind::String, + ExprStringLiteralKind::Docstring => StringLiteralKind::Docstring, + } + } + + const fn is_docstring(self) -> bool { + matches!(self, ExprStringLiteralKind::Docstring) + } } impl FormatRuleWithOptions> for FormatExprStringLiteral { - type Options = StringLayout; + type Options = ExprStringLiteralKind; fn with_options(mut self, options: Self::Options) -> Self { - self.layout = options; + self.kind = options; self } } impl FormatNodeRule for FormatExprStringLiteral { fn fmt_fields(&self, item: &ExprStringLiteral, f: &mut PyFormatter) -> FormatResult<()> { - FormatString::new(&AnyString::String(item)) - .with_layout(self.layout) - .fmt(f) + let ExprStringLiteral { value, .. } = item; + + match value.as_slice() { + [string_literal] => { + FormatStringLiteral::new(string_literal, self.kind.string_literal_kind()).fmt(f) + } + _ => { + // This is just a sanity check because [`DocstringStmt::try_from_statement`] + // ensures that the docstring is a *single* string literal. + assert!(!self.kind.is_docstring()); + + in_parentheses_only_group(&FormatStringContinuation::new(&AnyString::String(item))) + } + .fmt(f), + } } fn fmt_dangling_comments( @@ -46,7 +78,7 @@ impl NeedsParentheses for ExprStringLiteral { _parent: AnyNodeRef, context: &PyFormatContext, ) -> OptionalParentheses { - if self.implicit_concatenated { + if self.value.is_implicit_concatenated() { OptionalParentheses::Multiline } else if is_multiline_string(self.into(), context.source()) { OptionalParentheses::Never diff --git a/crates/ruff_python_formatter/src/expression/mod.rs b/crates/ruff_python_formatter/src/expression/mod.rs index 019546e596edd..7d858694c0436 100644 --- a/crates/ruff_python_formatter/src/expression/mod.rs +++ b/crates/ruff_python_formatter/src/expression/mod.rs @@ -12,9 +12,7 @@ use ruff_python_trivia::CommentRanges; use ruff_text_size::Ranged; use crate::builders::parenthesize_if_expands; -use crate::comments::{ - leading_comments, trailing_comments, LeadingDanglingTrailingComments, SourceComment, -}; +use crate::comments::{leading_comments, trailing_comments, LeadingDanglingTrailingComments}; use crate::context::{NodeLevel, WithNodeLevel}; use crate::expression::expr_generator_exp::is_generator_parenthesized; use crate::expression::expr_tuple::is_tuple_parenthesized; @@ -23,6 +21,7 @@ use crate::expression::parentheses::{ OptionalParentheses, Parentheses, Parenthesize, }; use crate::prelude::*; +use crate::preview::is_hug_parens_with_braces_and_square_brackets_enabled; mod binary_like; pub(crate) mod expr_attribute; @@ -37,7 +36,6 @@ pub(crate) mod expr_dict; pub(crate) mod expr_dict_comp; pub(crate) mod expr_ellipsis_literal; pub(crate) mod expr_f_string; -pub(crate) mod expr_formatted_value; pub(crate) mod expr_generator_exp; pub(crate) mod expr_if_exp; pub(crate) mod expr_ipy_escape_command; @@ -60,7 +58,6 @@ pub(crate) mod expr_yield; pub(crate) mod expr_yield_from; mod operator; pub(crate) mod parentheses; -pub(crate) mod string; #[derive(Copy, Clone, PartialEq, Eq, Default)] pub struct FormatExpr { @@ -98,7 +95,6 @@ impl FormatRule> for FormatExpr { Expr::YieldFrom(expr) => expr.format().fmt(f), Expr::Compare(expr) => expr.format().fmt(f), Expr::Call(expr) => expr.format().fmt(f), - Expr::FormattedValue(expr) => expr.format().fmt(f), Expr::FString(expr) => expr.format().fmt(f), Expr::StringLiteral(expr) => expr.format().fmt(f), Expr::BytesLiteral(expr) => expr.format().fmt(f), @@ -126,10 +122,12 @@ impl FormatRule> for FormatExpr { Parentheses::Never => false, }; if parenthesize { - let comment = f.context().comments().clone(); - let node_comments = comment.leading_dangling_trailing(expression); + let comments = f.context().comments().clone(); + let node_comments = comments.leading_dangling_trailing(expression); if !node_comments.has_leading() && !node_comments.has_trailing() { - parenthesized("(", &format_expr, ")").fmt(f) + parenthesized("(", &format_expr, ")") + .with_indent(!is_expression_huggable(expression, f.context())) + .fmt(f) } else { format_with_parentheses_comments(expression, &node_comments, f) } @@ -285,7 +283,6 @@ fn format_with_parentheses_comments( Expr::YieldFrom(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), Expr::Compare(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), Expr::Call(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), - Expr::FormattedValue(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), Expr::FString(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), Expr::StringLiteral(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), Expr::BytesLiteral(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), @@ -403,9 +400,11 @@ impl Format> for MaybeParenthesizeExpression<'_> { parenthesize_if_expands(&expression.format().with_options(Parentheses::Never)) .fmt(f) } + Parenthesize::IfRequired => { expression.format().with_options(Parentheses::Never).fmt(f) } + Parenthesize::Optional | Parenthesize::IfBreaks => { if can_omit_optional_parentheses(expression, f.context()) { optional_parentheses(&expression.format().with_options(Parentheses::Never)) @@ -427,113 +426,25 @@ impl Format> for MaybeParenthesizeExpression<'_> { Parenthesize::Optional | Parenthesize::IfRequired => { expression.format().with_options(Parentheses::Never).fmt(f) } + Parenthesize::IfBreaks => { - // Is the expression the last token in the parent statement. - // Excludes `await` and `yield` for which Black doesn't seem to apply the layout? - let last_expression = parent.is_stmt_assign() - || parent.is_stmt_ann_assign() - || parent.is_stmt_aug_assign() - || parent.is_stmt_return(); - - // Format the statements and value's trailing end of line comments: - // * after the expression if the expression needs no parentheses (necessary or the `expand_parent` makes the group never fit). - // * inside the parentheses if the expression exceeds the line-width. - // - // ```python - // a = long # with_comment - // b = ( - // short # with_comment - // ) - // - // # formatted - // a = ( - // long # with comment - // ) - // b = short # with comment - // ``` - // This matches Black's formatting with the exception that ruff applies this style also for - // attribute chains and non-fluent call expressions. See https://github.com/psf/black/issues/4001#issuecomment-1786681792 - // - // This logic isn't implemented in [`place_comment`] by associating trailing statement comments to the expression because - // doing so breaks the suite empty lines formatting that relies on trailing comments to be stored on the statement. - let (inline_comments, expression_trailing_comments) = if last_expression - && !( - // Ignore non-fluent attribute chains for black compatibility. - // See https://github.com/psf/black/issues/4001#issuecomment-1786681792 - expression.is_attribute_expr() - || expression.is_call_expr() - || expression.is_yield_from_expr() - || expression.is_yield_expr() - || expression.is_await_expr() - ) { - let parent_trailing_comments = comments.trailing(*parent); - let after_end_of_line = parent_trailing_comments - .partition_point(|comment| comment.line_position().is_end_of_line()); - let (stmt_inline_comments, _) = - parent_trailing_comments.split_at(after_end_of_line); - - let after_end_of_line = node_comments - .trailing - .partition_point(|comment| comment.line_position().is_end_of_line()); - - let (expression_inline_comments, expression_trailing_comments) = - node_comments.trailing.split_at(after_end_of_line); - - ( - OptionalParenthesesInlinedComments { - expression: expression_inline_comments, - statement: stmt_inline_comments, - }, - expression_trailing_comments, - ) + if node_comments.has_trailing() { + expression.format().with_options(Parentheses::Always).fmt(f) } else { - ( - OptionalParenthesesInlinedComments::default(), - node_comments.trailing, - ) - }; - - if expression_trailing_comments.is_empty() { // The group id is necessary because the nested expressions may reference it. let group_id = f.group_id("optional_parentheses"); let f = &mut WithNodeLevel::new(NodeLevel::Expression(Some(group_id)), f); - best_fit_parenthesize(&format_with(|f| { - inline_comments.mark_formatted(); - - expression - .format() - .with_options(Parentheses::Never) - .fmt(f)?; - - if !inline_comments.is_empty() { - // If the expressions exceeds the line width, format the comments in the parentheses - if_group_breaks(&inline_comments) - .with_group_id(Some(group_id)) - .fmt(f)?; - } - - Ok(()) - })) - .with_group_id(Some(group_id)) - .fmt(f)?; - - if !inline_comments.is_empty() { - // If the line fits into the line width, format the comments after the parenthesized expression - if_group_fits_on_line(&inline_comments) - .with_group_id(Some(group_id)) - .fmt(f)?; - } - - Ok(()) - } else { - expression.format().with_options(Parentheses::Always).fmt(f) + best_fit_parenthesize(&expression.format().with_options(Parentheses::Never)) + .with_group_id(Some(group_id)) + .fmt(f) } } }, OptionalParentheses::Never => match parenthesize { Parenthesize::IfBreaksOrIfRequired => { parenthesize_if_expands(&expression.format().with_options(Parentheses::Never)) + .with_indent(!is_expression_huggable(expression, f.context())) .fmt(f) } @@ -573,7 +484,6 @@ impl NeedsParentheses for Expr { Expr::YieldFrom(expr) => expr.needs_parentheses(parent, context), Expr::Compare(expr) => expr.needs_parentheses(parent, context), Expr::Call(expr) => expr.needs_parentheses(parent, context), - Expr::FormattedValue(expr) => expr.needs_parentheses(parent, context), Expr::FString(expr) => expr.needs_parentheses(parent, context), Expr::StringLiteral(expr) => expr.needs_parentheses(parent, context), Expr::BytesLiteral(expr) => expr.needs_parentheses(parent, context), @@ -618,19 +528,63 @@ impl<'ast> IntoFormat> for Expr { /// * The expression contains at least one parenthesized sub expression (optimization to avoid unnecessary work) /// /// This mimics Black's [`_maybe_split_omitting_optional_parens`](https://github.com/psf/black/blob/d1248ca9beaf0ba526d265f4108836d89cf551b7/src/black/linegen.py#L746-L820) +#[allow(clippy::if_same_then_else)] fn can_omit_optional_parentheses(expr: &Expr, context: &PyFormatContext) -> bool { let mut visitor = CanOmitOptionalParenthesesVisitor::new(context); visitor.visit_subexpression(expr); - if visitor.max_precedence == OperatorPrecedence::None { - true + if !visitor.any_parenthesized_expressions { + // Only use the more complex IR when there is any expression that we can possibly split by + false } else if visitor.max_precedence_count > 1 { false - } else if visitor.max_precedence == OperatorPrecedence::Attribute { + } else if visitor.max_precedence == OperatorPrecedence::None && expr.is_lambda_expr() { + // Micha: This seems to exclusively apply for lambda expressions where the body ends in a subscript. + // Subscripts are excluded by default because breaking them looks odd, but it seems to be fine for lambda expression. + // + // ```python + // mapper = lambda x: dict_with_default[ + // np.nan if isinstance(x, float) and np.isnan(x) else x + // ] + // ``` + // + // to prevent that it gets formatted as: + // + // ```python + // mapper = ( + // lambda x: dict_with_default[ + // np.nan if isinstance(x, float) and np.isnan(x) else x + // ] + // ) + // ``` + // I think we should remove this check in the future and instead parenthesize the body of the lambda expression: + // + // ```python + // mapper = lambda x: ( + // dict_with_default[ + // np.nan if isinstance(x, float) and np.isnan(x) else x + // ] + // ) + // ``` + true + } else if visitor.max_precedence == OperatorPrecedence::Attribute + && (expr.is_lambda_expr() || expr.is_named_expr_expr()) + { + // A single method call inside a named expression (`:=`) or as the body of a lambda function: + // ```python + // kwargs["open_with"] = lambda path, _: fsspec.open( + // path, "wb", **(storage_options or {}) + // ).open() + // + // if ret := subprocess.run( + // ["git", "rev-parse", "--short", "HEAD"], + // cwd=package_dir, + // capture_output=True, + // encoding="ascii", + // errors="surrogateescape", + // ).stdout: + // ``` true - } else if !visitor.any_parenthesized_expressions { - // Only use the more complex IR when there is any expression that we can possibly split by - false } else { fn is_parenthesized(expr: &Expr, context: &PyFormatContext) -> bool { // Don't break subscripts except in parenthesized context. It looks weird. @@ -641,17 +595,13 @@ fn can_omit_optional_parentheses(expr: &Expr, context: &PyFormatContext) -> bool // Only use the layout if the first expression starts with parentheses // or the last expression ends with parentheses of some sort, and // those parentheses are non-empty. - if visitor + visitor .last .is_some_and(|last| is_parenthesized(last, context)) - { - true - } else { - visitor + || visitor .first .expression() .is_some_and(|first| is_parenthesized(first, context)) - } } } @@ -778,16 +728,6 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { // Don't walk the slice, because the slice is always parenthesized. return; } - Expr::UnaryOp(ast::ExprUnaryOp { - range: _, - op, - operand: _, - }) => { - if op.is_invert() { - self.update_max_precedence(OperatorPrecedence::BitwiseInversion); - } - self.first.set_if_none(First::Token); - } // `[a, b].test.test[300].dot` Expr::Attribute(ast::ExprAttribute { @@ -804,23 +744,38 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { return; } - Expr::StringLiteral(ast::ExprStringLiteral { - implicit_concatenated: true, - .. - }) - | Expr::BytesLiteral(ast::ExprBytesLiteral { - implicit_concatenated: true, - .. - }) - | Expr::FString(ast::ExprFString { - implicit_concatenated: true, - .. - }) => { + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) + if value.is_implicit_concatenated() => + { self.update_max_precedence(OperatorPrecedence::String); } + Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) + if value.is_implicit_concatenated() => + { + self.update_max_precedence(OperatorPrecedence::String); + } + Expr::FString(ast::ExprFString { value, .. }) if value.is_implicit_concatenated() => { + self.update_max_precedence(OperatorPrecedence::String); + return; + } + + // Non terminal nodes that don't have a termination token. + Expr::NamedExpr(_) | Expr::GeneratorExp(_) | Expr::Tuple(_) => {} // Expressions with sub expressions but a preceding token // Mark this expression as first expression and not the sub expression. + // Visit the sub-expressions because the sub expressions may be the end of the entire expression. + Expr::UnaryOp(ast::ExprUnaryOp { + range: _, + op, + operand: _, + }) => { + if op.is_invert() { + self.update_max_precedence(OperatorPrecedence::BitwiseInversion); + } + self.first.set_if_none(First::Token); + } + Expr::Lambda(_) | Expr::Await(_) | Expr::Yield(_) @@ -829,11 +784,8 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { self.first.set_if_none(First::Token); } - Expr::Tuple(_) - | Expr::NamedExpr(_) - | Expr::GeneratorExp(_) - | Expr::FormattedValue(_) - | Expr::FString(_) + // Terminal nodes or nodes that wrap a sub-expression (where the sub expression can never be at the end). + Expr::FString(_) | Expr::StringLiteral(_) | Expr::BytesLiteral(_) | Expr::NumberLiteral(_) @@ -842,7 +794,9 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { | Expr::EllipsisLiteral(_) | Expr::Name(_) | Expr::Slice(_) - | Expr::IpyEscapeCommand(_) => {} + | Expr::IpyEscapeCommand(_) => { + return; + } }; walk_expr(self, expr); @@ -1043,7 +997,7 @@ impl OwnParentheses { /// Differs from [`has_own_parentheses`] in that it returns [`OwnParentheses::NonEmpty`] for /// parenthesized expressions, like `(1)` or `([1])`, regardless of whether those expression have /// their _own_ parentheses. -fn has_parentheses(expr: &Expr, context: &PyFormatContext) -> Option { +pub(crate) fn has_parentheses(expr: &Expr, context: &PyFormatContext) -> Option { let own_parentheses = has_own_parentheses(expr, context); // If the node has its own non-empty parentheses, we don't need to check for surrounding @@ -1120,6 +1074,85 @@ pub(crate) fn has_own_parentheses( } } +/// Returns `true` if the expression can hug directly to enclosing parentheses, as in Black's +/// `hug_parens_with_braces_and_square_brackets` preview style behavior. +/// +/// For example, in preview style, given: +/// ```python +/// ([1, 2, 3,]) +/// ``` +/// +/// We want to format it as: +/// ```python +/// ([ +/// 1, +/// 2, +/// 3, +/// ]) +/// ``` +/// +/// As opposed to: +/// ```python +/// ( +/// [ +/// 1, +/// 2, +/// 3, +/// ] +/// ) +/// ``` +pub(crate) fn is_expression_huggable(expr: &Expr, context: &PyFormatContext) -> bool { + if !is_hug_parens_with_braces_and_square_brackets_enabled(context) { + return false; + } + + match expr { + Expr::Tuple(_) + | Expr::List(_) + | Expr::Set(_) + | Expr::Dict(_) + | Expr::ListComp(_) + | Expr::SetComp(_) + | Expr::DictComp(_) => true, + + Expr::Starred(ast::ExprStarred { value, .. }) => matches!( + value.as_ref(), + Expr::Tuple(_) + | Expr::List(_) + | Expr::Set(_) + | Expr::Dict(_) + | Expr::ListComp(_) + | Expr::SetComp(_) + | Expr::DictComp(_) + ), + + Expr::BoolOp(_) + | Expr::NamedExpr(_) + | Expr::BinOp(_) + | Expr::UnaryOp(_) + | Expr::Lambda(_) + | Expr::IfExp(_) + | Expr::GeneratorExp(_) + | Expr::Await(_) + | Expr::Yield(_) + | Expr::YieldFrom(_) + | Expr::Compare(_) + | Expr::Call(_) + | Expr::FString(_) + | Expr::Attribute(_) + | Expr::Subscript(_) + | Expr::Name(_) + | Expr::Slice(_) + | Expr::IpyEscapeCommand(_) + | Expr::StringLiteral(_) + | Expr::BytesLiteral(_) + | Expr::NumberLiteral(_) + | Expr::BooleanLiteral(_) + | Expr::NoneLiteral(_) + | Expr::EllipsisLiteral(_) => false, + } +} + /// The precedence of [python operators](https://docs.python.org/3/reference/expressions.html#operator-precedence) from /// highest to lowest priority. /// @@ -1145,7 +1178,7 @@ enum OperatorPrecedence { Conditional, } -impl From for OperatorPrecedence { +impl From for OperatorPrecedence { fn from(value: Operator) -> Self { match value { Operator::Add | Operator::Sub => OperatorPrecedence::Additive, @@ -1162,41 +1195,3 @@ impl From for OperatorPrecedence { } } } - -#[derive(Debug, Default)] -struct OptionalParenthesesInlinedComments<'a> { - expression: &'a [SourceComment], - statement: &'a [SourceComment], -} - -impl<'a> OptionalParenthesesInlinedComments<'a> { - fn is_empty(&self) -> bool { - self.expression.is_empty() && self.statement.is_empty() - } - - fn iter_comments(&self) -> impl Iterator { - self.expression.iter().chain(self.statement) - } - - fn mark_formatted(&self) { - for comment in self.iter_comments() { - comment.mark_formatted(); - } - } -} - -impl Format> for OptionalParenthesesInlinedComments<'_> { - fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { - for comment in self.iter_comments() { - comment.mark_unformatted(); - } - - write!( - f, - [ - trailing_comments(self.expression), - trailing_comments(self.statement) - ] - ) - } -} diff --git a/crates/ruff_python_formatter/src/expression/parentheses.rs b/crates/ruff_python_formatter/src/expression/parentheses.rs index d05b9dcbd7d5f..d6a40f213b6ad 100644 --- a/crates/ruff_python_formatter/src/expression/parentheses.rs +++ b/crates/ruff_python_formatter/src/expression/parentheses.rs @@ -84,6 +84,7 @@ pub enum Parentheses { Never, } +/// Returns `true` if the [`ExpressionRef`] is enclosed by parentheses in the source code. pub(crate) fn is_expression_parenthesized( expr: ExpressionRef, comment_ranges: &CommentRanges, @@ -125,6 +126,7 @@ where FormatParenthesized { left, comments: &[], + indent: true, content: Argument::new(content), right, } @@ -133,6 +135,7 @@ where pub(crate) struct FormatParenthesized<'content, 'ast> { left: &'static str, comments: &'content [SourceComment], + indent: bool, content: Argument<'content, PyFormatContext<'ast>>, right: &'static str, } @@ -153,6 +156,11 @@ impl<'content, 'ast> FormatParenthesized<'content, 'ast> { ) -> FormatParenthesized<'content, 'ast> { FormatParenthesized { comments, ..self } } + + /// Whether to indent the content within the parentheses. + pub(crate) fn with_indent(self, indent: bool) -> FormatParenthesized<'content, 'ast> { + FormatParenthesized { indent, ..self } + } } impl<'ast> Format> for FormatParenthesized<'_, 'ast> { @@ -160,10 +168,15 @@ impl<'ast> Format> for FormatParenthesized<'_, 'ast> { let current_level = f.context().node_level(); let content = format_with(|f| { - group(&format_args![ - dangling_open_parenthesis_comments(self.comments), - soft_block_indent(&Arguments::from(&self.content)) - ]) + group(&format_with(|f| { + dangling_open_parenthesis_comments(self.comments).fmt(f)?; + if self.indent || !self.comments.is_empty() { + soft_block_indent(&Arguments::from(&self.content)).fmt(f)?; + } else { + Arguments::from(&self.content).fmt(f)?; + } + Ok(()) + })) .fmt(f) }); @@ -342,6 +355,26 @@ pub(super) fn write_in_parentheses_only_group_end_tag(f: &mut PyFormatter) { } } +/// Shows prints `content` only if the expression is enclosed by (optional) parentheses (`()`, `[]`, or `{}`) +/// and splits across multiple lines. +pub(super) fn in_parentheses_only_if_group_breaks<'a, T>( + content: T, +) -> impl Format> +where + T: Format>, +{ + format_with(move |f: &mut PyFormatter| match f.context().node_level() { + NodeLevel::TopLevel(_) | NodeLevel::CompoundStatement | NodeLevel::Expression(None) => { + // no-op, not parenthesized + Ok(()) + } + NodeLevel::Expression(Some(parentheses_id)) => if_group_breaks(&content) + .with_group_id(Some(parentheses_id)) + .fmt(f), + NodeLevel::ParenthesizedExpression => if_group_breaks(&content).fmt(f), + }) +} + /// Format comments inside empty parentheses, brackets or curly braces. /// /// Empty `()`, `[]` and `{}` are special because there can be dangling comments, and they can be in diff --git a/crates/ruff_python_formatter/src/expression/string.rs b/crates/ruff_python_formatter/src/expression/string.rs deleted file mode 100644 index 0fef24af91cf4..0000000000000 --- a/crates/ruff_python_formatter/src/expression/string.rs +++ /dev/null @@ -1,1165 +0,0 @@ -use std::borrow::Cow; - -use bitflags::bitflags; - -use ruff_formatter::{format_args, write, FormatError}; -use ruff_python_ast::AnyNodeRef; -use ruff_python_ast::{ - self as ast, ExprBytesLiteral, ExprFString, ExprStringLiteral, ExpressionRef, -}; -use ruff_python_parser::lexer::{lex_starts_at, LexicalError, LexicalErrorType}; -use ruff_python_parser::{Mode, Tok}; -use ruff_source_file::Locator; -use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; - -use crate::comments::{leading_comments, trailing_comments}; -use crate::expression::parentheses::{ - in_parentheses_only_group, in_parentheses_only_soft_line_break_or_space, -}; -use crate::expression::Expr; -use crate::prelude::*; -use crate::QuoteStyle; - -#[derive(Copy, Clone)] -enum Quoting { - CanChange, - Preserve, -} - -#[derive(Clone, Debug)] -pub(super) enum AnyString<'a> { - String(&'a ExprStringLiteral), - Bytes(&'a ExprBytesLiteral), - FString(&'a ExprFString), -} - -impl<'a> AnyString<'a> { - pub(crate) fn from_expression(expression: &'a Expr) -> Option> { - match expression { - Expr::StringLiteral(string) => Some(AnyString::String(string)), - Expr::BytesLiteral(bytes) => Some(AnyString::Bytes(bytes)), - Expr::FString(fstring) => Some(AnyString::FString(fstring)), - _ => None, - } - } - - fn quoting(&self, locator: &Locator) -> Quoting { - match self { - Self::String(_) | Self::Bytes(_) => Quoting::CanChange, - Self::FString(f_string) => { - let unprefixed = locator - .slice(f_string.range) - .trim_start_matches(|c| c != '"' && c != '\''); - let triple_quoted = - unprefixed.starts_with(r#"""""#) || unprefixed.starts_with(r"'''"); - if f_string.values.iter().any(|value| match value { - Expr::FormattedValue(ast::ExprFormattedValue { range, .. }) => { - let string_content = locator.slice(*range); - if triple_quoted { - string_content.contains(r#"""""#) || string_content.contains("'''") - } else { - string_content.contains(['"', '\'']) - } - } - _ => false, - }) { - Quoting::Preserve - } else { - Quoting::CanChange - } - } - } - } - - /// Returns `true` if the string is implicitly concatenated. - pub(super) fn is_implicit_concatenated(&self) -> bool { - match self { - Self::String(ExprStringLiteral { - implicit_concatenated, - .. - }) => *implicit_concatenated, - Self::Bytes(ExprBytesLiteral { - implicit_concatenated, - .. - }) => *implicit_concatenated, - Self::FString(ExprFString { - implicit_concatenated, - .. - }) => *implicit_concatenated, - } - } -} - -impl Ranged for AnyString<'_> { - fn range(&self) -> TextRange { - match self { - Self::String(expr) => expr.range(), - Self::Bytes(expr) => expr.range(), - Self::FString(expr) => expr.range(), - } - } -} - -impl<'a> From<&AnyString<'a>> for AnyNodeRef<'a> { - fn from(value: &AnyString<'a>) -> Self { - match value { - AnyString::String(expr) => AnyNodeRef::ExprStringLiteral(expr), - AnyString::Bytes(expr) => AnyNodeRef::ExprBytesLiteral(expr), - AnyString::FString(expr) => AnyNodeRef::ExprFString(expr), - } - } -} - -impl<'a> From<&AnyString<'a>> for ExpressionRef<'a> { - fn from(value: &AnyString<'a>) -> Self { - match value { - AnyString::String(expr) => ExpressionRef::StringLiteral(expr), - AnyString::Bytes(expr) => ExpressionRef::BytesLiteral(expr), - AnyString::FString(expr) => ExpressionRef::FString(expr), - } - } -} - -pub(super) struct FormatString<'a> { - string: &'a AnyString<'a>, - layout: StringLayout, -} - -#[derive(Default, Copy, Clone, Debug)] -pub enum StringLayout { - #[default] - Default, - DocString, - /// An implicit concatenated string in a binary like (e.g. `a + b` or `a < b`) expression. - /// - /// Formats the implicit concatenated string parts without the enclosing group because the group - /// is added by the binary like formatting. - ImplicitConcatenatedStringInBinaryLike, -} - -impl<'a> FormatString<'a> { - pub(super) fn new(string: &'a AnyString<'a>) -> Self { - Self { - string, - layout: StringLayout::Default, - } - } - - pub(super) fn with_layout(mut self, layout: StringLayout) -> Self { - self.layout = layout; - self - } -} - -impl<'a> Format> for FormatString<'a> { - fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { - let locator = f.context().locator(); - let result = match self.layout { - StringLayout::Default => { - if self.string.is_implicit_concatenated() { - in_parentheses_only_group(&FormatStringContinuation::new(self.string)).fmt(f) - } else { - StringPart::from_source(self.string.range(), &locator) - .normalize( - self.string.quoting(&locator), - &locator, - f.options().quote_style(), - ) - .fmt(f) - } - } - StringLayout::DocString => { - let string_part = StringPart::from_source(self.string.range(), &locator); - let normalized = - string_part.normalize(Quoting::CanChange, &locator, f.options().quote_style()); - format_docstring(&normalized, f) - } - StringLayout::ImplicitConcatenatedStringInBinaryLike => { - FormatStringContinuation::new(self.string).fmt(f) - } - }; - // TODO(dhruvmanila): With PEP 701, comments can be inside f-strings. - // This is to mark all of those comments as formatted but we need to - // figure out how to handle them. Note that this needs to be done only - // after the f-string is formatted, so only for all the non-formatted - // comments. - if let AnyString::FString(fstring) = self.string { - let comments = f.context().comments(); - fstring.values.iter().for_each(|value| { - comments.mark_verbatim_node_comments_formatted(value.into()); - }); - } - result - } -} - -/// A builder for the f-string range. -/// -/// For now, this is limited to the outermost f-string and doesn't support -/// nested f-strings. -#[derive(Debug, Default)] -struct FStringRangeBuilder { - start_location: TextSize, - end_location: TextSize, - nesting: u32, -} - -impl FStringRangeBuilder { - fn visit_token(&mut self, token: &Tok, range: TextRange) { - match token { - Tok::FStringStart => { - if self.nesting == 0 { - self.start_location = range.start(); - } - self.nesting += 1; - } - Tok::FStringEnd => { - // We can assume that this will never overflow because we know - // that the program once parsed to a valid AST which means that - // the start and end tokens for f-strings are balanced. - self.nesting -= 1; - if self.nesting == 0 { - self.end_location = range.end(); - } - } - _ => {} - } - } - - /// Returns `true` if the lexer is currently inside of a f-string. - /// - /// It'll return `false` once the `FStringEnd` token for the outermost - /// f-string is visited. - const fn in_fstring(&self) -> bool { - self.nesting > 0 - } - - /// Returns the complete range of the previously visited f-string. - /// - /// This method should only be called once the lexer is outside of any - /// f-string otherwise it might return an invalid range. - /// - /// It doesn't consume the builder because there can be multiple f-strings - /// throughout the source code. - fn finish(&self) -> TextRange { - debug_assert!(!self.in_fstring()); - TextRange::new(self.start_location, self.end_location) - } -} - -struct FormatStringContinuation<'a> { - string: &'a AnyString<'a>, -} - -impl<'a> FormatStringContinuation<'a> { - fn new(string: &'a AnyString<'a>) -> Self { - Self { string } - } -} - -impl Format> for FormatStringContinuation<'_> { - fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { - let comments = f.context().comments().clone(); - let locator = f.context().locator(); - let quote_style = f.options().quote_style(); - let mut dangling_comments = comments.dangling(self.string); - - let string_range = self.string.range(); - let string_content = locator.slice(string_range); - - // The AST parses implicit concatenation as a single string. - // Call into the lexer to extract the individual chunks and format each string on its own. - // This code does not yet implement the automatic joining of strings that fit on the same line - // because this is a black preview style. - let lexer = lex_starts_at(string_content, Mode::Expression, string_range.start()); - - // The lexer emits multiple tokens for a single f-string literal. Each token - // will have it's own range but we require the complete range of the f-string. - let mut fstring_range_builder = FStringRangeBuilder::default(); - - let mut joiner = f.join_with(in_parentheses_only_soft_line_break_or_space()); - - for token in lexer { - let (token, token_range) = match token { - Ok(spanned) => spanned, - Err(LexicalError { - error: LexicalErrorType::IndentationError, - .. - }) => { - // This can happen if the string continuation appears anywhere inside of a parenthesized expression - // because the lexer doesn't know about the parentheses. For example, the following snipped triggers an Indentation error - // ```python - // { - // "key": ( - // [], - // 'a' - // 'b' - // 'c' - // ) - // } - // ``` - // Ignoring the error here is *safe* because we know that the program once parsed to a valid AST. - continue; - } - Err(_) => { - return Err(FormatError::syntax_error( - "Unexpected lexer error in string formatting", - )); - } - }; - - fstring_range_builder.visit_token(&token, token_range); - - // We need to ignore all the tokens within the f-string as there can - // be `String` tokens inside it as well. For example, - // - // ```python - // f"foo {'bar'} foo" - // # ^^^^^ - // # Ignore any logic for this `String` token - // ``` - // - // Here, we're interested in the complete f-string, not the individual - // tokens inside it. - if fstring_range_builder.in_fstring() { - continue; - } - - match token { - Tok::String { .. } | Tok::FStringEnd => { - let token_range = if token.is_f_string_end() { - fstring_range_builder.finish() - } else { - token_range - }; - - // ```python - // ( - // "a" - // # leading - // "the comment above" - // ) - // ``` - let leading_comments_end = dangling_comments - .partition_point(|comment| comment.start() <= token_range.start()); - - let (leading_part_comments, rest) = - dangling_comments.split_at(leading_comments_end); - - // ```python - // ( - // "a" # trailing comment - // "the comment above" - // ) - // ``` - let trailing_comments_end = rest.partition_point(|comment| { - comment.line_position().is_end_of_line() - && !locator.contains_line_break(TextRange::new( - token_range.end(), - comment.start(), - )) - }); - - let (trailing_part_comments, rest) = rest.split_at(trailing_comments_end); - let part = StringPart::from_source(token_range, &locator); - let normalized = - part.normalize(self.string.quoting(&locator), &locator, quote_style); - - joiner.entry(&format_args![ - line_suffix_boundary(), - leading_comments(leading_part_comments), - normalized, - trailing_comments(trailing_part_comments) - ]); - - dangling_comments = rest; - } - Tok::Comment(_) - | Tok::NonLogicalNewline - | Tok::Newline - | Tok::Indent - | Tok::Dedent => continue, - token => unreachable!("Unexpected token {token:?}"), - } - } - - debug_assert!(dangling_comments.is_empty()); - - joiner.finish() - } -} - -#[derive(Debug)] -struct StringPart { - /// The prefix. - prefix: StringPrefix, - - /// The actual quotes of the string in the source - quotes: StringQuotes, - - /// The range of the string's content (full range minus quotes and prefix) - content_range: TextRange, -} - -impl StringPart { - fn from_source(range: TextRange, locator: &Locator) -> Self { - let string_content = locator.slice(range); - - let prefix = StringPrefix::parse(string_content); - let after_prefix = &string_content[usize::from(prefix.text_len())..]; - - let quotes = - StringQuotes::parse(after_prefix).expect("Didn't find string quotes after prefix"); - let relative_raw_content_range = TextRange::new( - prefix.text_len() + quotes.text_len(), - string_content.text_len() - quotes.text_len(), - ); - let raw_content_range = relative_raw_content_range + range.start(); - - Self { - prefix, - content_range: raw_content_range, - quotes, - } - } - - /// Computes the strings preferred quotes and normalizes its content. - fn normalize<'a>( - self, - quoting: Quoting, - locator: &'a Locator, - configured_style: QuoteStyle, - ) -> NormalizedString<'a> { - // Per PEP 8 and PEP 257, always prefer double quotes for docstrings and triple-quoted - // strings. (We assume docstrings are always triple-quoted.) - let preferred_style = if self.quotes.triple { - QuoteStyle::Double - } else { - configured_style - }; - - let raw_content = locator.slice(self.content_range); - - let quotes = match quoting { - Quoting::Preserve => self.quotes, - Quoting::CanChange => { - if self.prefix.is_raw_string() { - choose_quotes_raw(raw_content, self.quotes, preferred_style) - } else { - choose_quotes(raw_content, self.quotes, preferred_style) - } - } - }; - - let normalized = normalize_string(locator.slice(self.content_range), quotes, self.prefix); - - NormalizedString { - prefix: self.prefix, - content_range: self.content_range, - text: normalized, - quotes, - } - } -} - -#[derive(Debug)] -struct NormalizedString<'a> { - prefix: StringPrefix, - - /// The quotes of the normalized string (preferred quotes) - quotes: StringQuotes, - - /// The range of the string's content in the source (minus prefix and quotes). - content_range: TextRange, - - /// The normalized text - text: Cow<'a, str>, -} - -impl Ranged for NormalizedString<'_> { - fn range(&self) -> TextRange { - self.content_range - } -} - -impl Format> for NormalizedString<'_> { - fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { - write!(f, [self.prefix, self.quotes])?; - match &self.text { - Cow::Borrowed(_) => { - source_text_slice(self.range()).fmt(f)?; - } - Cow::Owned(normalized) => { - text(normalized, Some(self.start())).fmt(f)?; - } - } - self.quotes.fmt(f) - } -} - -bitflags! { - #[derive(Copy, Clone, Debug, PartialEq, Eq)] - pub(super) struct StringPrefix: u8 { - const UNICODE = 0b0000_0001; - /// `r"test"` - const RAW = 0b0000_0010; - /// `R"test" - const RAW_UPPER = 0b0000_0100; - const BYTE = 0b0000_1000; - const F_STRING = 0b0001_0000; - } -} - -impl StringPrefix { - pub(super) fn parse(input: &str) -> StringPrefix { - let chars = input.chars(); - let mut prefix = StringPrefix::empty(); - - for c in chars { - let flag = match c { - 'u' | 'U' => StringPrefix::UNICODE, - 'f' | 'F' => StringPrefix::F_STRING, - 'b' | 'B' => StringPrefix::BYTE, - 'r' => StringPrefix::RAW, - 'R' => StringPrefix::RAW_UPPER, - '\'' | '"' => break, - c => { - unreachable!( - "Unexpected character '{c}' terminating the prefix of a string literal" - ); - } - }; - - prefix |= flag; - } - - prefix - } - - pub(super) const fn text_len(self) -> TextSize { - TextSize::new(self.bits().count_ones()) - } - - pub(super) const fn is_raw_string(self) -> bool { - self.contains(StringPrefix::RAW) || self.contains(StringPrefix::RAW_UPPER) - } - - pub(super) const fn is_fstring(self) -> bool { - self.contains(StringPrefix::F_STRING) - } -} - -impl Format> for StringPrefix { - fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { - // Retain the casing for the raw prefix: - // https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#r-strings-and-r-strings - if self.contains(StringPrefix::RAW) { - token("r").fmt(f)?; - } else if self.contains(StringPrefix::RAW_UPPER) { - token("R").fmt(f)?; - } - - if self.contains(StringPrefix::BYTE) { - token("b").fmt(f)?; - } - - if self.contains(StringPrefix::F_STRING) { - token("f").fmt(f)?; - } - - // Remove the unicode prefix `u` if any because it is meaningless in Python 3+. - - Ok(()) - } -} - -/// Choose the appropriate quote style for a raw string. -/// -/// The preferred quote style is chosen unless the string contains unescaped quotes of the -/// preferred style. For example, `r"foo"` is chosen over `r'foo'` if the preferred quote -/// style is double quotes. -fn choose_quotes_raw( - input: &str, - quotes: StringQuotes, - preferred_style: QuoteStyle, -) -> StringQuotes { - let preferred_quote_char = preferred_style.as_char(); - let mut chars = input.chars().peekable(); - let contains_unescaped_configured_quotes = loop { - match chars.next() { - Some('\\') => { - // Ignore escaped characters - chars.next(); - } - // `"` or `'` - Some(c) if c == preferred_quote_char => { - if !quotes.triple { - break true; - } - - match chars.peek() { - // We can't turn `r'''\""'''` into `r"""\"""""`, this would confuse the parser - // about where the closing triple quotes start - None => break true, - Some(next) if *next == preferred_quote_char => { - // `""` or `''` - chars.next(); - - // We can't turn `r'''""'''` into `r""""""""`, nor can we have - // `"""` or `'''` respectively inside the string - if chars.peek().is_none() || chars.peek() == Some(&preferred_quote_char) { - break true; - } - } - _ => {} - } - } - Some(_) => continue, - None => break false, - } - }; - - StringQuotes { - triple: quotes.triple, - style: if contains_unescaped_configured_quotes { - quotes.style - } else { - preferred_style - }, - } -} - -/// Choose the appropriate quote style for a string. -/// -/// For single quoted strings, the preferred quote style is used, unless the alternative quote style -/// would require fewer escapes. -/// -/// For triple quoted strings, the preferred quote style is always used, unless the string contains -/// a triplet of the quote character (e.g., if double quotes are preferred, double quotes will be -/// used unless the string contains `"""`). -fn choose_quotes(input: &str, quotes: StringQuotes, preferred_style: QuoteStyle) -> StringQuotes { - let style = if quotes.triple { - // True if the string contains a triple quote sequence of the configured quote style. - let mut uses_triple_quotes = false; - let mut chars = input.chars().peekable(); - - while let Some(c) = chars.next() { - let preferred_quote_char = preferred_style.as_char(); - match c { - '\\' => { - if matches!(chars.peek(), Some('"' | '\\')) { - chars.next(); - } - } - // `"` or `'` - c if c == preferred_quote_char => { - match chars.peek().copied() { - Some(c) if c == preferred_quote_char => { - // `""` or `''` - chars.next(); - - match chars.peek().copied() { - Some(c) if c == preferred_quote_char => { - // `"""` or `'''` - chars.next(); - uses_triple_quotes = true; - break; - } - Some(_) => {} - None => { - // Handle `''' ""'''`. At this point we have consumed both - // double quotes, so on the next iteration the iterator is empty - // and we'd miss the string ending with a preferred quote - uses_triple_quotes = true; - break; - } - } - } - Some(_) => { - // A single quote char, this is ok - } - None => { - // Trailing quote at the end of the comment - uses_triple_quotes = true; - break; - } - } - } - _ => continue, - } - } - - if uses_triple_quotes { - // String contains a triple quote sequence of the configured quote style. - // Keep the existing quote style. - quotes.style - } else { - preferred_style - } - } else { - let mut single_quotes = 0u32; - let mut double_quotes = 0u32; - - for c in input.chars() { - match c { - '\'' => { - single_quotes += 1; - } - - '"' => { - double_quotes += 1; - } - - _ => continue, - } - } - - match preferred_style { - QuoteStyle::Single => { - if single_quotes > double_quotes { - QuoteStyle::Double - } else { - QuoteStyle::Single - } - } - QuoteStyle::Double => { - if double_quotes > single_quotes { - QuoteStyle::Single - } else { - QuoteStyle::Double - } - } - } - }; - - StringQuotes { - triple: quotes.triple, - style, - } -} - -#[derive(Copy, Clone, Debug)] -pub(super) struct StringQuotes { - triple: bool, - style: QuoteStyle, -} - -impl StringQuotes { - pub(super) fn parse(input: &str) -> Option { - let mut chars = input.chars(); - - let quote_char = chars.next()?; - let style = QuoteStyle::try_from(quote_char).ok()?; - - let triple = chars.next() == Some(quote_char) && chars.next() == Some(quote_char); - - Some(Self { triple, style }) - } - - pub(super) const fn is_triple(self) -> bool { - self.triple - } - - const fn text_len(self) -> TextSize { - if self.triple { - TextSize::new(3) - } else { - TextSize::new(1) - } - } -} - -impl Format> for StringQuotes { - fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { - let quotes = match (self.style, self.triple) { - (QuoteStyle::Single, false) => "'", - (QuoteStyle::Single, true) => "'''", - (QuoteStyle::Double, false) => "\"", - (QuoteStyle::Double, true) => "\"\"\"", - }; - - token(quotes).fmt(f) - } -} - -/// Adds the necessary quote escapes and removes unnecessary escape sequences when quoting `input` -/// with the provided [`StringQuotes`] style. -/// -/// Returns the normalized string and whether it contains new lines. -fn normalize_string(input: &str, quotes: StringQuotes, prefix: StringPrefix) -> Cow { - // The normalized string if `input` is not yet normalized. - // `output` must remain empty if `input` is already normalized. - let mut output = String::new(); - // Tracks the last index of `input` that has been written to `output`. - // If `last_index` is `0` at the end, then the input is already normalized and can be returned as is. - let mut last_index = 0; - - let style = quotes.style; - let preferred_quote = style.as_char(); - let opposite_quote = style.invert().as_char(); - - let mut chars = input.char_indices().peekable(); - - let is_raw = prefix.is_raw_string(); - let is_fstring = prefix.is_fstring(); - let mut formatted_value_nesting = 0u32; - - while let Some((index, c)) = chars.next() { - if is_fstring && matches!(c, '{' | '}') { - if chars.peek().copied().is_some_and(|(_, next)| next == c) { - // Skip over the second character of the double braces - chars.next(); - } else if c == '{' { - formatted_value_nesting += 1; - } else { - // Safe to assume that `c == '}'` here because of the matched pattern above - formatted_value_nesting = formatted_value_nesting.saturating_sub(1); - } - continue; - } - if c == '\r' { - output.push_str(&input[last_index..index]); - - // Skip over the '\r' character, keep the `\n` - if chars.peek().copied().is_some_and(|(_, next)| next == '\n') { - chars.next(); - } - // Replace the `\r` with a `\n` - else { - output.push('\n'); - } - - last_index = index + '\r'.len_utf8(); - } else if !quotes.triple && !is_raw { - if c == '\\' { - if let Some((_, next)) = chars.peek().copied() { - #[allow(clippy::if_same_then_else)] - if next == opposite_quote && formatted_value_nesting == 0 { - // Remove the escape by ending before the backslash and starting again with the quote - chars.next(); - output.push_str(&input[last_index..index]); - last_index = index + '\\'.len_utf8(); - } else if next == preferred_quote { - // Quote is already escaped, skip over it. - chars.next(); - } else if next == '\\' { - // Skip over escaped backslashes - chars.next(); - } - } - } else if c == preferred_quote && formatted_value_nesting == 0 { - // Escape the quote - output.push_str(&input[last_index..index]); - output.push('\\'); - output.push(c); - last_index = index + preferred_quote.len_utf8(); - } - } - } - - let normalized = if last_index == 0 { - Cow::Borrowed(input) - } else { - output.push_str(&input[last_index..]); - Cow::Owned(output) - }; - - normalized -} - -/// For docstring indentation, black counts spaces as 1 and tabs by increasing the indentation up -/// to the next multiple of 8. This is effectively a port of -/// [`str.expandtabs`](https://docs.python.org/3/library/stdtypes.html#str.expandtabs), -/// which black [calls with the default tab width of 8](https://github.com/psf/black/blob/c36e468794f9256d5e922c399240d49782ba04f1/src/black/strings.py#L61). -fn indentation_length(line: &str) -> TextSize { - let mut indentation = 0u32; - for char in line.chars() { - if char == '\t' { - // Pad to the next multiple of tab_width - indentation += 8 - (indentation.rem_euclid(8)); - } else if char.is_whitespace() { - indentation += u32::from(char.text_len()); - } else { - break; - } - } - TextSize::new(indentation) -} - -/// Format a docstring by trimming whitespace and adjusting the indentation. -/// -/// Summary of changes we make: -/// * Normalize the string like all other strings -/// * Ignore docstring that have an escaped newline -/// * Trim all trailing whitespace, except for a chaperone space that avoids quotes or backslashes -/// in the last line. -/// * Trim leading whitespace on the first line, again except for a chaperone space -/// * If there is only content in the first line and after that only whitespace, collapse the -/// docstring into one line -/// * Adjust the indentation (see below) -/// -/// # Docstring indentation -/// -/// Unlike any other string, like black we change the indentation of docstring lines. -/// -/// We want to preserve the indentation inside the docstring relative to the suite statement/block -/// indent that the docstring statement is in, but also want to apply the change of the outer -/// indentation in the docstring, e.g. -/// ```python -/// def sparkle_sky(): -/// """Make a pretty sparkly sky. -/// * * ✨ *. . -/// * * ✨ . -/// . * . ✨ * . . -/// """ -/// ``` -/// should become -/// ```python -/// def sparkle_sky(): -/// """Make a pretty sparkly sky. -/// * * ✨ *. . -/// * * ✨ . -/// . * . ✨ * . . -/// """ -/// ``` -/// We can't compute the full indentation here since we don't know what the block indent of -/// the doc comment will be yet and which we can only have added by formatting each line -/// separately with a hard line break. This means we need to strip shared indentation from -/// docstring while preserving the in-docstring bigger-than-suite-statement indentation. Example: -/// ```python -/// def f(): -/// """first line -/// line a -/// line b -/// """ -/// ``` -/// The docstring indentation is 2, the block indents will change this to 4 (but we can't -/// determine this at this point). The indentation of line a is 2, so we trim ` line a` -/// to `line a`. For line b it's 5, so we trim it to `line b` and pad with 5-2=3 spaces to -/// ` line b`. The closing quotes, being on their own line, are stripped get only the -/// default indentation. Fully formatted: -/// ```python -/// def f(): -/// """first line -/// line a -/// line b -/// """ -/// ``` -/// -/// Tabs are counted by padding them to the next multiple of 8 according to -/// [`str.expandtabs`](https://docs.python.org/3/library/stdtypes.html#str.expandtabs). When -/// we see indentation that contains a tab or any other none ascii-space whitespace we rewrite the -/// string. -/// -/// Additionally, if any line in the docstring has less indentation than the docstring -/// (effectively a negative indentation wrt. to the current level), we pad all lines to the -/// level of the docstring with spaces. -/// ```python -/// def f(): -/// """first line -/// line a -/// line b -/// line c -/// """ -/// ``` -/// Here line a is 3 columns negatively indented, so we pad all lines by an extra 3 spaces: -/// ```python -/// def f(): -/// """first line -/// line a -/// line b -/// line c -/// """ -/// ``` -fn format_docstring(normalized: &NormalizedString, f: &mut PyFormatter) -> FormatResult<()> { - let docstring = &normalized.text; - - // Black doesn't change the indentation of docstrings that contain an escaped newline - if docstring.contains("\\\n") { - return normalized.fmt(f); - } - - // is_borrowed is unstable :/ - let already_normalized = matches!(docstring, Cow::Borrowed(_)); - - let mut lines = docstring.lines().peekable(); - - // Start the string - write!( - f, - [ - normalized.prefix, - normalized.quotes, - source_position(normalized.start()), - ] - )?; - // We track where in the source docstring we are (in source code byte offsets) - let mut offset = normalized.start(); - - // The first line directly after the opening quotes has different rules than the rest, mainly - // that we remove all leading whitespace as there's no indentation - let first = lines.next().unwrap_or_default(); - // Black trims whitespace using [`str.strip()`](https://docs.python.org/3/library/stdtypes.html#str.strip) - // https://github.com/psf/black/blob/b4dca26c7d93f930bbd5a7b552807370b60d4298/src/black/strings.py#L77-L85 - // So we use the unicode whitespace definition through `trim_{start,end}` instead of the python - // tokenizer whitespace definition in `trim_whitespace_{start,end}`. - let trim_end = first.trim_end(); - let trim_both = trim_end.trim_start(); - - // Edge case: The first line is `""" "content`, so we need to insert chaperone space that keep - // inner quotes and closing quotes from getting to close to avoid `""""content` - if trim_both.starts_with(normalized.quotes.style.as_char()) { - space().fmt(f)?; - } - - if !trim_end.is_empty() { - // For the first line of the docstring we strip the leading and trailing whitespace, e.g. - // `""" content ` to `"""content` - let leading_whitespace = trim_end.text_len() - trim_both.text_len(); - let trimmed_line_range = - TextRange::at(offset, trim_end.text_len()).add_start(leading_whitespace); - if already_normalized { - source_text_slice(trimmed_line_range).fmt(f)?; - } else { - text(trim_both, Some(trimmed_line_range.start())).fmt(f)?; - } - } - offset += first.text_len(); - - // Check if we have a single line (or empty) docstring - if docstring[first.len()..].trim().is_empty() { - // For `"""\n"""` or other whitespace between the quotes, black keeps a single whitespace, - // but `""""""` doesn't get one inserted. - if needs_chaperone_space(normalized, trim_end) - || (trim_end.is_empty() && !docstring.is_empty()) - { - space().fmt(f)?; - } - normalized.quotes.fmt(f)?; - return Ok(()); - } - - hard_line_break().fmt(f)?; - // We know that the normalized string has \n line endings - offset += "\n".text_len(); - - // If some line of the docstring is less indented than the function body, we pad all lines to - // align it with the docstring statement. Conversely, if all lines are over-indented, we strip - // the extra indentation. We call this stripped indentation since it's relative to the block - // indent printer-made indentation. - let stripped_indentation = lines - .clone() - // We don't want to count whitespace-only lines as miss-indented - .filter(|line| !line.trim().is_empty()) - .map(indentation_length) - .min() - .unwrap_or_default(); - - while let Some(line) = lines.next() { - let is_last = lines.peek().is_none(); - format_docstring_line( - line, - is_last, - offset, - stripped_indentation, - already_normalized, - f, - )?; - // We know that the normalized string has \n line endings - offset += line.text_len() + "\n".text_len(); - } - - // Same special case in the last line as for the first line - let trim_end = docstring - .as_ref() - .trim_end_matches(|c: char| c.is_whitespace() && c != '\n'); - if needs_chaperone_space(normalized, trim_end) { - space().fmt(f)?; - } - - write!(f, [source_position(normalized.end()), normalized.quotes]) -} - -/// If the last line of the docstring is `content" """` or `content\ """`, we need a chaperone space -/// that avoids `content""""` and `content\"""`. This does only applies to un-escaped backslashes, -/// so `content\\ """` doesn't need a space while `content\\\ """` does. -fn needs_chaperone_space(normalized: &NormalizedString, trim_end: &str) -> bool { - trim_end.ends_with(normalized.quotes.style.as_char()) - || trim_end.chars().rev().take_while(|c| *c == '\\').count() % 2 == 1 -} - -/// Format a docstring line that is not the first line -fn format_docstring_line( - line: &str, - is_last: bool, - offset: TextSize, - stripped_indentation_length: TextSize, - already_normalized: bool, - f: &mut PyFormatter, -) -> FormatResult<()> { - let trim_end = line.trim_end(); - if trim_end.is_empty() { - return if is_last { - // If the doc string ends with ` """`, the last line is ` `, but we don't want to - // insert an empty line (but close the docstring) - Ok(()) - } else { - empty_line().fmt(f) - }; - } - - let tab_or_non_ascii_space = trim_end - .chars() - .take_while(|c| c.is_whitespace()) - .any(|c| c != ' '); - - if tab_or_non_ascii_space { - // We strip the indentation that is shared with the docstring statement, unless a line - // was indented less than the docstring statement, in which we strip only this much - // indentation to implicitly pad all lines by the difference, or all lines were - // overindented, in which case we strip the additional whitespace (see example in - // [`format_docstring`] doc comment). We then prepend the in-docstring indentation to the - // string. - let indent_len = indentation_length(trim_end) - stripped_indentation_length; - let in_docstring_indent = " ".repeat(usize::from(indent_len)) + trim_end.trim_start(); - text(&in_docstring_indent, Some(offset)).fmt(f)?; - } else { - // Take the string with the trailing whitespace removed, then also skip the leading - // whitespace - let trimmed_line_range = - TextRange::at(offset, trim_end.text_len()).add_start(stripped_indentation_length); - if already_normalized { - source_text_slice(trimmed_line_range).fmt(f)?; - } else { - // All indents are ascii spaces, so the slicing is correct - text( - &trim_end[usize::from(stripped_indentation_length)..], - Some(trimmed_line_range.start()), - ) - .fmt(f)?; - } - } - - // We handled the case that the closing quotes are on their own line above (the last line is - // empty except for whitespace). If they are on the same line as content, we don't insert a line - // break. - if !is_last { - hard_line_break().fmt(f)?; - } - - Ok(()) -} - -#[cfg(test)] -mod tests { - use crate::expression::string::indentation_length; - use ruff_text_size::TextSize; - - #[test] - fn test_indentation_like_black() { - assert_eq!(indentation_length("\t \t \t"), TextSize::new(24)); - assert_eq!(indentation_length("\t \t"), TextSize::new(24)); - assert_eq!(indentation_length("\t\t\t"), TextSize::new(24)); - assert_eq!(indentation_length(" "), TextSize::new(4)); - } -} diff --git a/crates/ruff_python_formatter/src/generated.rs b/crates/ruff_python_formatter/src/generated.rs index dfa93b8961ac3..a5217a11d1487 100644 --- a/crates/ruff_python_formatter/src/generated.rs +++ b/crates/ruff_python_formatter/src/generated.rs @@ -1534,42 +1534,6 @@ impl<'ast> IntoFormat> for ast::ExprCall { } } -impl FormatRule> - for crate::expression::expr_formatted_value::FormatExprFormattedValue -{ - #[inline] - fn fmt(&self, node: &ast::ExprFormattedValue, f: &mut PyFormatter) -> FormatResult<()> { - FormatNodeRule::::fmt(self, node, f) - } -} -impl<'ast> AsFormat> for ast::ExprFormattedValue { - type Format<'a> = FormatRefWithRule< - 'a, - ast::ExprFormattedValue, - crate::expression::expr_formatted_value::FormatExprFormattedValue, - PyFormatContext<'ast>, - >; - fn format(&self) -> Self::Format<'_> { - FormatRefWithRule::new( - self, - crate::expression::expr_formatted_value::FormatExprFormattedValue::default(), - ) - } -} -impl<'ast> IntoFormat> for ast::ExprFormattedValue { - type Format = FormatOwnedWithRule< - ast::ExprFormattedValue, - crate::expression::expr_formatted_value::FormatExprFormattedValue, - PyFormatContext<'ast>, - >; - fn into_format(self) -> Self::Format { - FormatOwnedWithRule::new( - self, - crate::expression::expr_formatted_value::FormatExprFormattedValue::default(), - ) - } -} - impl FormatRule> for crate::expression::expr_f_string::FormatExprFString { @@ -2978,3 +2942,39 @@ impl<'ast> IntoFormat> for ast::TypeParamParamSpec { ) } } + +impl FormatRule> + for crate::other::bytes_literal::FormatBytesLiteral +{ + #[inline] + fn fmt(&self, node: &ast::BytesLiteral, f: &mut PyFormatter) -> FormatResult<()> { + FormatNodeRule::::fmt(self, node, f) + } +} +impl<'ast> AsFormat> for ast::BytesLiteral { + type Format<'a> = FormatRefWithRule< + 'a, + ast::BytesLiteral, + crate::other::bytes_literal::FormatBytesLiteral, + PyFormatContext<'ast>, + >; + fn format(&self) -> Self::Format<'_> { + FormatRefWithRule::new( + self, + crate::other::bytes_literal::FormatBytesLiteral::default(), + ) + } +} +impl<'ast> IntoFormat> for ast::BytesLiteral { + type Format = FormatOwnedWithRule< + ast::BytesLiteral, + crate::other::bytes_literal::FormatBytesLiteral, + PyFormatContext<'ast>, + >; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule::new( + self, + crate::other::bytes_literal::FormatBytesLiteral::default(), + ) + } +} diff --git a/crates/ruff_python_formatter/src/lib.rs b/crates/ruff_python_formatter/src/lib.rs index d85806e3dfc63..05f122606bd79 100644 --- a/crates/ruff_python_formatter/src/lib.rs +++ b/crates/ruff_python_formatter/src/lib.rs @@ -15,7 +15,10 @@ use crate::comments::{ dangling_comments, leading_comments, trailing_comments, Comments, SourceComment, }; pub use crate::context::PyFormatContext; -pub use crate::options::{MagicTrailingComma, PreviewMode, PyFormatOptions, QuoteStyle}; +pub use crate::options::{ + DocstringCode, DocstringCodeLineWidth, MagicTrailingComma, PreviewMode, PyFormatOptions, + QuoteStyle, +}; pub use crate::shared_traits::{AsFormat, FormattedIter, FormattedIterExt, IntoFormat}; use crate::verbatim::suppressed_node; @@ -30,8 +33,10 @@ mod options; pub(crate) mod other; pub(crate) mod pattern; mod prelude; +mod preview; mod shared_traits; pub(crate) mod statement; +pub(crate) mod string; pub(crate) mod type_param; mod verbatim; diff --git a/crates/ruff_python_formatter/src/options.rs b/crates/ruff_python_formatter/src/options.rs index b39c7b6ff79c6..4f637dca9ee10 100644 --- a/crates/ruff_python_formatter/src/options.rs +++ b/crates/ruff_python_formatter/src/options.rs @@ -11,7 +11,7 @@ use std::str::FromStr; #[cfg_attr( feature = "serde", derive(serde::Serialize, serde::Deserialize), - serde(default) + serde(default, deny_unknown_fields) )] pub struct PyFormatOptions { /// Whether we're in a `.py` file or `.pyi` file, which have different rules. @@ -43,6 +43,17 @@ pub struct PyFormatOptions { /// in the formatted document. source_map_generation: SourceMapGeneration, + /// Whether to format code snippets in docstrings or not. + /// + /// By default this is disabled (opt-in), but the plan is to make this + /// enabled by default (opt-out) in the future. + docstring_code: DocstringCode, + + /// The preferred line width at which the formatter should wrap lines in + /// docstring code examples. This only has an impact when `docstring_code` + /// is enabled. + docstring_code_line_width: DocstringCodeLineWidth, + /// Whether preview style formatting is enabled or not preview: PreviewMode, } @@ -70,6 +81,8 @@ impl Default for PyFormatOptions { line_ending: LineEnding::default(), magic_trailing_comma: MagicTrailingComma::default(), source_map_generation: SourceMapGeneration::default(), + docstring_code: DocstringCode::default(), + docstring_code_line_width: DocstringCodeLineWidth::default(), preview: PreviewMode::default(), } } @@ -108,7 +121,15 @@ impl PyFormatOptions { self.line_ending } - pub fn preview(&self) -> PreviewMode { + pub fn docstring_code(&self) -> DocstringCode { + self.docstring_code + } + + pub fn docstring_code_line_width(&self) -> DocstringCodeLineWidth { + self.docstring_code_line_width + } + + pub const fn preview(&self) -> PreviewMode { self.preview } @@ -148,6 +169,18 @@ impl PyFormatOptions { self } + #[must_use] + pub fn with_docstring_code(mut self, docstring_code: DocstringCode) -> Self { + self.docstring_code = docstring_code; + self + } + + #[must_use] + pub fn with_docstring_code_line_width(mut self, line_width: DocstringCodeLineWidth) -> Self { + self.docstring_code_line_width = line_width; + self + } + #[must_use] pub fn with_preview(mut self, preview: PreviewMode) -> Self { self.preview = preview; @@ -190,35 +223,7 @@ pub enum QuoteStyle { Single, #[default] Double, -} - -impl QuoteStyle { - pub const fn as_char(self) -> char { - match self { - QuoteStyle::Single => '\'', - QuoteStyle::Double => '"', - } - } - - #[must_use] - pub const fn invert(self) -> QuoteStyle { - match self { - QuoteStyle::Single => QuoteStyle::Double, - QuoteStyle::Double => QuoteStyle::Single, - } - } -} - -impl TryFrom for QuoteStyle { - type Error = (); - - fn try_from(value: char) -> std::result::Result { - match value { - '\'' => Ok(QuoteStyle::Single), - '"' => Ok(QuoteStyle::Double), - _ => Err(()), - } - } + Preserve, } impl FromStr for QuoteStyle { @@ -228,6 +233,7 @@ impl FromStr for QuoteStyle { match s { "\"" | "double" | "Double" => Ok(Self::Double), "'" | "single" | "Single" => Ok(Self::Single), + "preserve" | "Preserve" => Ok(Self::Preserve), // TODO: replace this error with a diagnostic _ => Err("Value not supported for QuoteStyle"), } @@ -284,3 +290,62 @@ impl PreviewMode { matches!(self, PreviewMode::Enabled) } } + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +pub enum DocstringCode { + #[default] + Disabled, + + Enabled, +} + +impl DocstringCode { + pub const fn is_enabled(self) -> bool { + matches!(self, DocstringCode::Enabled) + } +} + +#[derive(Copy, Clone, Default, Eq, PartialEq, CacheKey)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] +#[cfg_attr(feature = "serde", serde(untagged))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +pub enum DocstringCodeLineWidth { + Fixed(LineWidth), + #[default] + #[cfg_attr( + feature = "serde", + serde(deserialize_with = "deserialize_docstring_code_line_width_dynamic") + )] + Dynamic, +} + +impl std::fmt::Debug for DocstringCodeLineWidth { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match *self { + DocstringCodeLineWidth::Fixed(v) => v.value().fmt(f), + DocstringCodeLineWidth::Dynamic => "dynamic".fmt(f), + } + } +} + +/// Responsible for deserializing the `DocstringCodeLineWidth::Dynamic` +/// variant. +fn deserialize_docstring_code_line_width_dynamic<'de, D>(d: D) -> Result<(), D::Error> +where + D: serde::Deserializer<'de>, +{ + use serde::{de::Error, Deserialize}; + + let value = String::deserialize(d)?; + match &*value { + "dynamic" => Ok(()), + s => Err(D::Error::invalid_value( + serde::de::Unexpected::Str(s), + &"dynamic", + )), + } +} diff --git a/crates/ruff_python_formatter/src/other/arguments.rs b/crates/ruff_python_formatter/src/other/arguments.rs index 5baa9fa741c46..d57e168c89459 100644 --- a/crates/ruff_python_formatter/src/other/arguments.rs +++ b/crates/ruff_python_formatter/src/other/arguments.rs @@ -1,12 +1,15 @@ -use ruff_formatter::write; +use ruff_formatter::{write, FormatContext}; use ruff_python_ast::{ArgOrKeyword, Arguments, Expr}; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::comments::SourceComment; use crate::expression::expr_generator_exp::GeneratorExpParentheses; +use crate::expression::is_expression_huggable; use crate::expression::parentheses::{empty_parenthesized, parenthesized, Parentheses}; +use crate::other::commas; use crate::prelude::*; +use crate::preview::is_hug_parens_with_braces_and_square_brackets_enabled; #[derive(Default)] pub struct FormatArguments; @@ -104,6 +107,7 @@ impl FormatNodeRule for FormatArguments { // ) // ``` parenthesized("(", &group(&all_arguments), ")") + .with_indent(!is_argument_huggable(item, f.context())) .with_dangling_comments(dangling_comments) ] ) @@ -143,3 +147,69 @@ fn is_single_argument_parenthesized(argument: &Expr, call_end: TextSize, source: false } +/// Returns `true` if the arguments can hug directly to the enclosing parentheses in the call, as +/// in Black's `hug_parens_with_braces_and_square_brackets` preview style behavior. +/// +/// For example, in preview style, given: +/// ```python +/// func([1, 2, 3,]) +/// ``` +/// +/// We want to format it as: +/// ```python +/// func([ +/// 1, +/// 2, +/// 3, +/// ]) +/// ``` +/// +/// As opposed to: +/// ```python +/// func( +/// [ +/// 1, +/// 2, +/// 3, +/// ] +/// ) +/// ``` +/// +/// Hugging should only be applied to single-argument collections, like lists, or starred versions +/// of those collections. +fn is_argument_huggable(item: &Arguments, context: &PyFormatContext) -> bool { + if !is_hug_parens_with_braces_and_square_brackets_enabled(context) { + return false; + } + + // Find the lone argument or `**kwargs` keyword. + let arg = match (item.args.as_slice(), item.keywords.as_slice()) { + ([arg], []) => arg, + ([], [keyword]) if keyword.arg.is_none() && !context.comments().has(keyword) => { + &keyword.value + } + _ => return false, + }; + + // If the expression itself isn't huggable, then we can't hug it. + if !is_expression_huggable(arg, context) { + return false; + } + + // If the expression has leading or trailing comments, then we can't hug it. + let comments = context.comments().leading_dangling_trailing(arg); + if comments.has_leading() || comments.has_trailing() { + return false; + } + + let options = context.options(); + + // If the expression has a trailing comma, then we can't hug it. + if options.magic_trailing_comma().is_respect() + && commas::has_magic_trailing_comma(TextRange::new(arg.end(), item.end()), options, context) + { + return false; + } + + true +} diff --git a/crates/ruff_python_formatter/src/other/bytes_literal.rs b/crates/ruff_python_formatter/src/other/bytes_literal.rs new file mode 100644 index 0000000000000..c6445c8d6adc3 --- /dev/null +++ b/crates/ruff_python_formatter/src/other/bytes_literal.rs @@ -0,0 +1,23 @@ +use ruff_python_ast::BytesLiteral; +use ruff_text_size::Ranged; + +use crate::prelude::*; +use crate::string::{Quoting, StringPart}; + +#[derive(Default)] +pub struct FormatBytesLiteral; + +impl FormatNodeRule for FormatBytesLiteral { + fn fmt_fields(&self, item: &BytesLiteral, f: &mut PyFormatter) -> FormatResult<()> { + let locator = f.context().locator(); + + StringPart::from_source(item.range(), &locator) + .normalize( + Quoting::CanChange, + &locator, + f.options().quote_style(), + f.context().docstring(), + ) + .fmt(f) + } +} diff --git a/crates/ruff_python_formatter/src/other/f_string.rs b/crates/ruff_python_formatter/src/other/f_string.rs new file mode 100644 index 0000000000000..da81162c2ef54 --- /dev/null +++ b/crates/ruff_python_formatter/src/other/f_string.rs @@ -0,0 +1,49 @@ +use ruff_python_ast::FString; +use ruff_text_size::Ranged; + +use crate::prelude::*; +use crate::string::{Quoting, StringPart}; + +/// Formats an f-string which is part of a larger f-string expression. +/// +/// For example, this would be used to format the f-string part in `"foo" f"bar {x}"` +/// or the standalone f-string in `f"foo {x} bar"`. +pub(crate) struct FormatFString<'a> { + value: &'a FString, + /// The quoting of an f-string. This is determined by the parent node + /// (f-string expression) and is required to format an f-string correctly. + quoting: Quoting, +} + +impl<'a> FormatFString<'a> { + pub(crate) fn new(value: &'a FString, quoting: Quoting) -> Self { + Self { value, quoting } + } +} + +impl Format> for FormatFString<'_> { + fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { + let locator = f.context().locator(); + + let result = StringPart::from_source(self.value.range(), &locator) + .normalize( + self.quoting, + &locator, + f.options().quote_style(), + f.context().docstring(), + ) + .fmt(f); + + // TODO(dhruvmanila): With PEP 701, comments can be inside f-strings. + // This is to mark all of those comments as formatted but we need to + // figure out how to handle them. Note that this needs to be done only + // after the f-string is formatted, so only for all the non-formatted + // comments. + let comments = f.context().comments(); + self.value.elements.iter().for_each(|value| { + comments.mark_verbatim_node_comments_formatted(value.into()); + }); + + result + } +} diff --git a/crates/ruff_python_formatter/src/other/f_string_part.rs b/crates/ruff_python_formatter/src/other/f_string_part.rs new file mode 100644 index 0000000000000..c471b5fc8cd4f --- /dev/null +++ b/crates/ruff_python_formatter/src/other/f_string_part.rs @@ -0,0 +1,39 @@ +use ruff_python_ast::FStringPart; + +use crate::other::f_string::FormatFString; +use crate::other::string_literal::{FormatStringLiteral, StringLiteralKind}; +use crate::prelude::*; +use crate::string::Quoting; + +/// Formats an f-string part which is either a string literal or an f-string. +/// +/// This delegates the actual formatting to the appropriate formatter. +pub(crate) struct FormatFStringPart<'a> { + part: &'a FStringPart, + /// The quoting to be used for all the f-string parts. This is determined by + /// the parent node (f-string expression) and is required to format all parts + /// correctly. + quoting: Quoting, +} + +impl<'a> FormatFStringPart<'a> { + pub(crate) fn new(part: &'a FStringPart, quoting: Quoting) -> Self { + Self { part, quoting } + } +} + +impl Format> for FormatFStringPart<'_> { + fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { + match self.part { + FStringPart::Literal(string_literal) => FormatStringLiteral::new( + string_literal, + // If an f-string part is a string literal, the f-string is always + // implicitly concatenated e.g., `"foo" f"bar {x}"`. A standalone + // string literal would be a string expression, not an f-string. + StringLiteralKind::InImplicitlyConcatenatedFString(self.quoting), + ) + .fmt(f), + FStringPart::FString(f_string) => FormatFString::new(f_string, self.quoting).fmt(f), + } + } +} diff --git a/crates/ruff_python_formatter/src/other/mod.rs b/crates/ruff_python_formatter/src/other/mod.rs index e7eb28ae7f4fd..d07339f717cbf 100644 --- a/crates/ruff_python_formatter/src/other/mod.rs +++ b/crates/ruff_python_formatter/src/other/mod.rs @@ -1,14 +1,18 @@ pub(crate) mod alias; pub(crate) mod arguments; +pub(crate) mod bytes_literal; pub(crate) mod commas; pub(crate) mod comprehension; pub(crate) mod decorator; pub(crate) mod elif_else_clause; pub(crate) mod except_handler_except_handler; +pub(crate) mod f_string; +pub(crate) mod f_string_part; pub(crate) mod identifier; pub(crate) mod keyword; pub(crate) mod match_case; pub(crate) mod parameter; pub(crate) mod parameter_with_default; pub(crate) mod parameters; +pub(crate) mod string_literal; pub(crate) mod with_item; diff --git a/crates/ruff_python_formatter/src/other/parameters.rs b/crates/ruff_python_formatter/src/other/parameters.rs index 86cad5869b2ce..c3e251ebe97e5 100644 --- a/crates/ruff_python_formatter/src/other/parameters.rs +++ b/crates/ruff_python_formatter/src/other/parameters.rs @@ -252,6 +252,19 @@ impl FormatNodeRule for FormatParameters { let mut f = WithNodeLevel::new(NodeLevel::ParenthesizedExpression, f); // No parameters, format any dangling comments between `()` write!(f, [empty_parenthesized("(", dangling, ")")]) + } else if num_parameters == 1 && posonlyargs.is_empty() && kwonlyargs.is_empty() { + // If we have a single argument, avoid the inner group, to ensure that we insert a + // trailing comma if the outer group breaks. + let mut f = WithNodeLevel::new(NodeLevel::ParenthesizedExpression, f); + write!( + f, + [ + token("("), + dangling_open_parenthesis_comments(parenthesis_dangling), + soft_block_indent(&format_inner), + token(")") + ] + ) } else { // Intentionally avoid `parenthesized`, which groups the entire formatted contents. // We want parameters to be grouped alongside return types, one level up, so we diff --git a/crates/ruff_python_formatter/src/other/string_literal.rs b/crates/ruff_python_formatter/src/other/string_literal.rs new file mode 100644 index 0000000000000..e23db85707830 --- /dev/null +++ b/crates/ruff_python_formatter/src/other/string_literal.rs @@ -0,0 +1,72 @@ +use ruff_python_ast::StringLiteral; +use ruff_text_size::Ranged; + +use crate::prelude::*; +use crate::string::{docstring, Quoting, StringPart}; +use crate::QuoteStyle; + +pub(crate) struct FormatStringLiteral<'a> { + value: &'a StringLiteral, + layout: StringLiteralKind, +} + +impl<'a> FormatStringLiteral<'a> { + pub(crate) fn new(value: &'a StringLiteral, layout: StringLiteralKind) -> Self { + Self { value, layout } + } +} + +/// The kind of a string literal. +#[derive(Copy, Clone, Debug, Default)] +pub(crate) enum StringLiteralKind { + /// A normal string literal e.g., `"foo"`. + #[default] + String, + /// A string literal used as a docstring. + Docstring, + /// A string literal that is implicitly concatenated with an f-string. This + /// makes the overall expression an f-string whose quoting detection comes + /// from the parent node (f-string expression). + InImplicitlyConcatenatedFString(Quoting), +} + +impl StringLiteralKind { + /// Checks if this string literal is a docstring. + pub(crate) const fn is_docstring(self) -> bool { + matches!(self, StringLiteralKind::Docstring) + } + + /// Returns the quoting to be used for this string literal. + fn quoting(self) -> Quoting { + match self { + StringLiteralKind::String | StringLiteralKind::Docstring => Quoting::CanChange, + StringLiteralKind::InImplicitlyConcatenatedFString(quoting) => quoting, + } + } +} + +impl Format> for FormatStringLiteral<'_> { + fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { + let locator = f.context().locator(); + + let quote_style = if self.layout.is_docstring() { + // Per PEP 8 and PEP 257, always prefer double quotes for docstrings + QuoteStyle::Double + } else { + f.options().quote_style() + }; + + let normalized = StringPart::from_source(self.value.range(), &locator).normalize( + self.layout.quoting(), + &locator, + quote_style, + f.context().docstring(), + ); + + if self.layout.is_docstring() { + docstring::format(&normalized, f) + } else { + normalized.fmt(f) + } + } +} diff --git a/crates/ruff_python_formatter/src/preview.rs b/crates/ruff_python_formatter/src/preview.rs new file mode 100644 index 0000000000000..90379d1ad8fab --- /dev/null +++ b/crates/ruff_python_formatter/src/preview.rs @@ -0,0 +1,26 @@ +//! Helpers to test if a specific preview style is enabled or not. +//! +//! The motivation for these functions isn't to avoid code duplication but to ease promoting preview styles +//! to stable. The challenge with directly using [`is_preview`](PyFormatContext::is_preview) is that it is unclear +//! for which specific feature this preview check is for. Having named functions simplifies the promotion: +//! Simply delete the function and let Rust tell you which checks you have to remove. +use crate::PyFormatContext; + +/// Returns `true` if the [`fix_power_op_line_length`](https://github.com/astral-sh/ruff/issues/8938) preview style is enabled. +pub(crate) const fn is_fix_power_op_line_length_enabled(context: &PyFormatContext) -> bool { + context.is_preview() +} + +/// Returns `true` if the [`hug_parens_with_braces_and_square_brackets`](https://github.com/astral-sh/ruff/issues/8279) preview style is enabled. +pub(crate) const fn is_hug_parens_with_braces_and_square_brackets_enabled( + context: &PyFormatContext, +) -> bool { + context.is_preview() +} + +/// Returns `true` if the [`prefer_splitting_right_hand_side_of_assignments`](https://github.com/astral-sh/ruff/issues/6975) preview style is enabled. +pub(crate) const fn is_prefer_splitting_right_hand_side_of_assignments_enabled( + context: &PyFormatContext, +) -> bool { + context.is_preview() +} diff --git a/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs b/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs index cb5f5fa745278..89a97acc6f454 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs @@ -2,10 +2,12 @@ use ruff_formatter::write; use ruff_python_ast::StmtAnnAssign; use crate::comments::{SourceComment, SuppressionKind}; - -use crate::expression::maybe_parenthesize_expression; -use crate::expression::parentheses::Parenthesize; +use crate::expression::has_parentheses; use crate::prelude::*; +use crate::preview::is_prefer_splitting_right_hand_side_of_assignments_enabled; +use crate::statement::stmt_assign::{ + AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression, +}; use crate::statement::trailing_semicolon; #[derive(Default)] @@ -21,21 +23,33 @@ impl FormatNodeRule for FormatStmtAnnAssign { simple: _, } = item; - write!( - f, - [target.format(), token(":"), space(), annotation.format(),] - )?; + write!(f, [target.format(), token(":"), space()])?; if let Some(value) = value { - write!( - f, - [ - space(), - token("="), - space(), - maybe_parenthesize_expression(value, item, Parenthesize::IfBreaks) - ] - )?; + if is_prefer_splitting_right_hand_side_of_assignments_enabled(f.context()) + && has_parentheses(annotation, f.context()).is_some() + { + FormatStatementsLastExpression::RightToLeft { + before_operator: AnyBeforeOperator::Expression(annotation), + operator: AnyAssignmentOperator::Assign, + value, + statement: item.into(), + } + .fmt(f)?; + } else { + write!( + f, + [ + annotation.format(), + space(), + token("="), + space(), + FormatStatementsLastExpression::left_to_right(value, item) + ] + )?; + } + } else { + annotation.format().fmt(f)?; } if f.options().source_type().is_ipynb() diff --git a/crates/ruff_python_formatter/src/statement/stmt_assign.rs b/crates/ruff_python_formatter/src/statement/stmt_assign.rs index 7a8a5fd2be005..9430e7289a210 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_assign.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_assign.rs @@ -1,11 +1,17 @@ use ruff_formatter::{format_args, write, FormatError}; -use ruff_python_ast::{Expr, StmtAssign}; +use ruff_python_ast::{AnyNodeRef, Expr, Operator, StmtAssign, TypeParams}; -use crate::comments::{SourceComment, SuppressionKind}; +use crate::builders::parenthesize_if_expands; +use crate::comments::{ + trailing_comments, Comments, LeadingDanglingTrailingComments, SourceComment, SuppressionKind, +}; use crate::context::{NodeLevel, WithNodeLevel}; -use crate::expression::parentheses::{Parentheses, Parenthesize}; +use crate::expression::parentheses::{ + is_expression_parenthesized, NeedsParentheses, OptionalParentheses, Parentheses, Parenthesize, +}; use crate::expression::{has_own_parentheses, maybe_parenthesize_expression}; use crate::prelude::*; +use crate::preview::is_prefer_splitting_right_hand_side_of_assignments_enabled; use crate::statement::trailing_semicolon; #[derive(Default)] @@ -23,31 +29,66 @@ impl FormatNodeRule for FormatStmtAssign { "Expected at least on assignment target", ))?; - write!( - f, - [ - first.format(), - space(), - token("="), - space(), - FormatTargets { targets: rest } - ] - )?; + // The first target is special because it never gets parenthesized nor does the formatter remove parentheses if unnecessary. + let format_first = FormatTargetWithEqualOperator { + target: first, + preserve_parentheses: true, + }; - write!( - f, - [maybe_parenthesize_expression( - value, - item, - Parenthesize::IfBreaks - )] - )?; + if is_prefer_splitting_right_hand_side_of_assignments_enabled(f.context()) { + // Avoid parenthesizing the value if the last target before the assigned value expands. + if let Some((last, head)) = rest.split_last() { + format_first.fmt(f)?; + + for target in head { + FormatTargetWithEqualOperator { + target, + preserve_parentheses: false, + } + .fmt(f)?; + } + + FormatStatementsLastExpression::RightToLeft { + before_operator: AnyBeforeOperator::Expression(last), + operator: AnyAssignmentOperator::Assign, + value, + statement: item.into(), + } + .fmt(f)?; + } + // Avoid parenthesizing the value for single-target assignments that where the + // target has its own parentheses (list, dict, tuple, ...) and the target expands. + else if has_target_own_parentheses(first, f.context()) + && !is_expression_parenthesized( + first.into(), + f.context().comments().ranges(), + f.context().source(), + ) + { + FormatStatementsLastExpression::RightToLeft { + before_operator: AnyBeforeOperator::Expression(first), + operator: AnyAssignmentOperator::Assign, + value, + statement: item.into(), + } + .fmt(f)?; + } + // For single targets that have no split points, parenthesize the value only + // if it makes it fit. Otherwise omit the parentheses. + else { + format_first.fmt(f)?; + FormatStatementsLastExpression::left_to_right(value, item).fmt(f)?; + } + } else { + write!(f, [format_first, FormatTargets { targets: rest }])?; + + FormatStatementsLastExpression::left_to_right(value, item).fmt(f)?; + } if f.options().source_type().is_ipynb() && f.context().node_level().is_last_top_level_statement() - && rest.is_empty() - && first.is_name_expr() && trailing_semicolon(item.into(), f.context().source()).is_some() + && matches!(targets.as_slice(), [Expr::Name(_)]) { token(";").fmt(f)?; } @@ -64,6 +105,7 @@ impl FormatNodeRule for FormatStmtAssign { } } +/// Formats the targets so that they split left-to right. #[derive(Debug)] struct FormatTargets<'a> { targets: &'a [Expr], @@ -74,9 +116,9 @@ impl Format> for FormatTargets<'_> { if let Some((first, rest)) = self.targets.split_first() { let comments = f.context().comments(); - let parenthesize = if comments.has_leading(first) { + let parenthesize = if comments.has_leading(first) || comments.has_trailing(first) { ParenthesizeTarget::Always - } else if has_own_parentheses(first, f.context()).is_some() { + } else if has_target_own_parentheses(first, f.context()) { ParenthesizeTarget::Never } else { ParenthesizeTarget::IfBreaks @@ -133,3 +175,565 @@ enum ParenthesizeTarget { Never, IfBreaks, } + +/// Formats a single target with the equal operator. +struct FormatTargetWithEqualOperator<'a> { + target: &'a Expr, + + /// Whether parentheses should be preserved as in the source or if the target + /// should only be parenthesized if necessary (because of comments or because it doesn't fit). + preserve_parentheses: bool, +} + +impl Format> for FormatTargetWithEqualOperator<'_> { + fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { + // Preserve parentheses for the first target or around targets with leading or trailing comments. + if self.preserve_parentheses + || f.context().comments().has_leading(self.target) + || f.context().comments().has_trailing(self.target) + { + self.target.format().fmt(f)?; + } else if has_target_own_parentheses(self.target, f.context()) { + self.target + .format() + .with_options(Parentheses::Never) + .fmt(f)?; + } else { + parenthesize_if_expands(&self.target.format().with_options(Parentheses::Never)) + .fmt(f)?; + } + + write!(f, [space(), token("="), space()]) + } +} + +/// Formats the last expression in statements that start with a keyword (like `return`) or after an operator (assignments). +/// +/// The implementation avoids parenthesizing unsplittable values (like `None`, `True`, `False`, Names, a subset of strings) +/// if the value won't fit even when parenthesized. +/// +/// ## Trailing comments +/// Trailing comments are inlined inside the `value`'s parentheses rather than formatted at the end +/// of the statement for unsplittable values if the `value` gets parenthesized. +/// +/// Inlining the trailing comments prevent situations where the parenthesized value +/// still exceeds the configured line width, but parenthesizing helps to make the trailing comment fit. +/// Instead, it only parenthesizes `value` if it makes both the `value` and the trailing comment fit. +/// See [PR 8431](https://github.com/astral-sh/ruff/pull/8431) for more details. +/// +/// The implementation formats the statement's and value's trailing end of line comments: +/// * after the expression if the expression needs no parentheses (necessary or the `expand_parent` makes the group never fit). +/// * inside the parentheses if the expression exceeds the line-width. +/// +/// ```python +/// a = loooooooooooooooooooooooooooong # with_comment +/// b = ( +/// short # with_comment +/// ) +/// ``` +/// +/// Which gets formatted to: +/// +/// ```python +/// # formatted +/// a = ( +/// loooooooooooooooooooooooooooong # with comment +/// ) +/// b = short # with comment +/// ``` +/// +/// The long name gets parenthesized because it exceeds the configured line width and the trailing comment of the +/// statement gets formatted inside (instead of outside) the parentheses. +/// +/// No parentheses are added for `short` because it fits into the configured line length, regardless of whether +/// the comment exceeds the line width or not. +/// +/// This logic isn't implemented in [`place_comment`] by associating trailing statement comments to the expression because +/// doing so breaks the suite empty lines formatting that relies on trailing comments to be stored on the statement. +pub(super) enum FormatStatementsLastExpression<'a> { + /// Prefers to split what's left of `value` before splitting the value. + /// + /// ```python + /// aaaaaaa[bbbbbbbb] = some_long_value + /// ``` + /// + /// This layout splits `aaaaaaa[bbbbbbbb]` first assuming the whole statements exceeds the line width, resulting in + /// + /// ```python + /// aaaaaaa[ + /// bbbbbbbb + /// ] = some_long_value + /// ``` + /// + /// This layout is preferred over [`RightToLeft`] if the left is unsplittable (single keyword like `return` or a Name) + /// because it has better performance characteristics. + LeftToRight { + /// The right side of an assignment or the value returned in a return statement. + value: &'a Expr, + + /// The parent statement that encloses the `value` expression. + statement: AnyNodeRef<'a>, + }, + + /// Prefers parenthesizing the value before splitting the left side. Specific to assignments. + /// + /// Formats what's left of `value` together with the assignment operator and the assigned `value`. + /// This layout prefers parenthesizing the value over parenthesizing the left (target or type annotation): + /// + /// ```python + /// aaaaaaa[bbbbbbbb] = some_long_value + /// ``` + /// + /// gets formatted to... + /// + /// ```python + /// aaaaaaa[bbbbbbbb] = ( + /// some_long_value + /// ) + /// ``` + /// + /// ... regardless whether the value will fit or not. + /// + /// The left only gets parenthesized if the left exceeds the configured line width on its own or + /// is forced to split because of a magical trailing comma or contains comments: + /// + /// ```python + /// aaaaaaa[bbbbbbbb_exceeds_the_line_width] = some_long_value + /// ``` + /// + /// gets formatted to + /// ```python + /// aaaaaaa[ + /// bbbbbbbb_exceeds_the_line_width + /// ] = some_long_value + /// ``` + /// + /// The layout avoids parenthesizing the value when the left splits to avoid + /// unnecessary parentheses. Adding the parentheses, as shown in the below example, reduces readability. + /// + /// ```python + /// aaaaaaa[ + /// bbbbbbbb_exceeds_the_line_width + /// ] = ( + /// some_long_value + /// ) + /// + /// ## Non-fluent Call Expressions + /// Non-fluent call expressions in the `value` position are only parenthesized if the opening parentheses + /// exceeds the configured line length. The layout prefers splitting after the opening parentheses + /// if the `callee` expression and the opening parentheses fit. + /// fits on the line. + RightToLeft { + /// The expression that comes before the assignment operator. This is either + /// the last target, or the type annotation of an annotated assignment. + before_operator: AnyBeforeOperator<'a>, + + /// The assignment operator. Either `Assign` (`=`) or the operator used by the augmented assignment statement. + operator: AnyAssignmentOperator, + + /// The assigned `value`. + value: &'a Expr, + + /// The assignment statement. + statement: AnyNodeRef<'a>, + }, +} + +impl<'a> FormatStatementsLastExpression<'a> { + pub(super) fn left_to_right>>(value: &'a Expr, statement: S) -> Self { + Self::LeftToRight { + value, + statement: statement.into(), + } + } +} + +impl Format> for FormatStatementsLastExpression<'_> { + fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { + match self { + FormatStatementsLastExpression::LeftToRight { value, statement } => { + let can_inline_comment = should_inline_comments(value, *statement, f.context()); + + if !can_inline_comment { + return maybe_parenthesize_expression( + value, + *statement, + Parenthesize::IfBreaks, + ) + .fmt(f); + } + + let comments = f.context().comments().clone(); + let expression_comments = comments.leading_dangling_trailing(*value); + + if let Some(inline_comments) = OptionalParenthesesInlinedComments::new( + &expression_comments, + *statement, + &comments, + ) { + let group_id = f.group_id("optional_parentheses"); + + let f = &mut WithNodeLevel::new(NodeLevel::Expression(Some(group_id)), f); + + best_fit_parenthesize(&format_with(|f| { + inline_comments.mark_formatted(); + + value.format().with_options(Parentheses::Never).fmt(f)?; + + if !inline_comments.is_empty() { + // If the expressions exceeds the line width, format the comments in the parentheses + if_group_breaks(&inline_comments).fmt(f)?; + } + + Ok(()) + })) + .with_group_id(Some(group_id)) + .fmt(f)?; + + if !inline_comments.is_empty() { + // If the line fits into the line width, format the comments after the parenthesized expression + if_group_fits_on_line(&inline_comments) + .with_group_id(Some(group_id)) + .fmt(f)?; + } + + Ok(()) + } else { + // Preserve the parentheses if the expression has any leading or trailing comments, + // to avoid syntax errors, similar to `maybe_parenthesize_expression`. + value.format().with_options(Parentheses::Always).fmt(f) + } + } + FormatStatementsLastExpression::RightToLeft { + before_operator, + operator, + value, + statement, + } => { + let should_inline_comments = should_inline_comments(value, *statement, f.context()); + + // Use the normal `maybe_parenthesize_layout` for splittable `value`s. + if !should_inline_comments + && !should_non_inlineable_use_best_fit(value, *statement, f.context()) + { + return write!( + f, + [ + before_operator, + space(), + operator, + space(), + maybe_parenthesize_expression( + value, + *statement, + Parenthesize::IfBreaks + ) + ] + ); + } + + let comments = f.context().comments().clone(); + let expression_comments = comments.leading_dangling_trailing(*value); + + // Don't inline comments for attribute and call expressions for black compatibility + let inline_comments = if should_inline_comments { + OptionalParenthesesInlinedComments::new( + &expression_comments, + *statement, + &comments, + ) + } else if expression_comments.has_leading() + || expression_comments.has_trailing_own_line() + { + None + } else { + Some(OptionalParenthesesInlinedComments::default()) + }; + + let Some(inline_comments) = inline_comments else { + // Preserve the parentheses if the expression has any leading or trailing own line comments + // same as `maybe_parenthesize_expression` + return write!( + f, + [ + before_operator, + space(), + operator, + space(), + value.format().with_options(Parentheses::Always) + ] + ); + }; + + // Prevent inline comments to be formatted as part of the expression. + inline_comments.mark_formatted(); + + let mut last_target = before_operator.memoized(); + + // Don't parenthesize the `value` if it is known that the target will break. + // This is mainly a performance optimisation that avoids unnecessary memoization + // and using the costly `BestFitting` layout if it is already known that only the last variant + // can ever fit because the left breaks. + if last_target.inspect(f)?.will_break() { + return write!( + f, + [ + last_target, + space(), + operator, + space(), + value.format().with_options(Parentheses::Never), + inline_comments + ] + ); + } + + let format_value = value.format().with_options(Parentheses::Never).memoized(); + + // Tries to fit the `left` and the `value` on a single line: + // ```python + // a = b = c + // ``` + let format_flat = format_with(|f| { + write!( + f, + [ + last_target, + space(), + operator, + space(), + format_value, + inline_comments + ] + ) + }); + + // Don't break the last assignment target but parenthesize the value to see if it fits (break right first). + // + // ```python + // a["bbbbb"] = ( + // c + // ) + // ``` + let format_parenthesize_value = format_with(|f| { + write!( + f, + [ + last_target, + space(), + operator, + space(), + token("("), + block_indent(&format_args![format_value, inline_comments]), + token(")") + ] + ) + }); + + // Fall back to parenthesizing (or splitting) the last target part if we can't make the value + // fit. Don't parenthesize the value to avoid unnecessary parentheses. + // + // ```python + // a[ + // "bbbbb" + // ] = c + // ``` + let format_split_left = format_with(|f| { + write!( + f, + [ + last_target, + space(), + operator, + space(), + format_value, + inline_comments + ] + ) + }); + + // For call expressions, prefer breaking after the call expression's opening parentheses + // over parenthesizing the entire call expression. + if value.is_call_expr() { + best_fitting![ + format_flat, + // Avoid parenthesizing the call expression if the `(` fit on the line + format_args![ + last_target, + space(), + operator, + space(), + group(&format_value).should_expand(true), + ], + format_parenthesize_value, + format_split_left + ] + .fmt(f) + } else { + best_fitting![format_flat, format_parenthesize_value, format_split_left].fmt(f) + } + } + } + } +} + +#[derive(Debug, Default)] +struct OptionalParenthesesInlinedComments<'a> { + expression: &'a [SourceComment], + statement: &'a [SourceComment], +} + +impl<'a> OptionalParenthesesInlinedComments<'a> { + fn new( + expression_comments: &LeadingDanglingTrailingComments<'a>, + statement: AnyNodeRef<'a>, + comments: &'a Comments<'a>, + ) -> Option { + if expression_comments.has_leading() || expression_comments.has_trailing_own_line() { + return None; + } + + let statement_trailing_comments = comments.trailing(statement); + let after_end_of_line = statement_trailing_comments + .partition_point(|comment| comment.line_position().is_end_of_line()); + let (stmt_inline_comments, _) = statement_trailing_comments.split_at(after_end_of_line); + + let after_end_of_line = expression_comments + .trailing + .partition_point(|comment| comment.line_position().is_end_of_line()); + + let (expression_inline_comments, trailing_own_line_comments) = + expression_comments.trailing.split_at(after_end_of_line); + + debug_assert!(trailing_own_line_comments.is_empty(), "The method should have returned early if the expression has trailing own line comments"); + + Some(OptionalParenthesesInlinedComments { + expression: expression_inline_comments, + statement: stmt_inline_comments, + }) + } + + fn is_empty(&self) -> bool { + self.expression.is_empty() && self.statement.is_empty() + } + + fn iter_comments(&self) -> impl Iterator { + self.expression.iter().chain(self.statement) + } + + fn mark_formatted(&self) { + for comment in self.expression { + comment.mark_formatted(); + } + } +} + +impl Format> for OptionalParenthesesInlinedComments<'_> { + fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { + for comment in self.iter_comments() { + comment.mark_unformatted(); + } + + write!( + f, + [ + trailing_comments(self.expression), + trailing_comments(self.statement) + ] + ) + } +} + +#[derive(Copy, Clone, Debug)] +pub(super) enum AnyAssignmentOperator { + Assign, + AugAssign(Operator), +} + +impl Format> for AnyAssignmentOperator { + fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { + match self { + AnyAssignmentOperator::Assign => token("=").fmt(f), + AnyAssignmentOperator::AugAssign(operator) => { + write!(f, [operator.format(), token("=")]) + } + } + } +} + +#[derive(Copy, Clone, Debug)] +pub(super) enum AnyBeforeOperator<'a> { + Expression(&'a Expr), + TypeParams(&'a TypeParams), +} + +impl Format> for AnyBeforeOperator<'_> { + fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { + match self { + AnyBeforeOperator::Expression(expression) => { + // Preserve parentheses around targets with comments. + if f.context().comments().has_leading(*expression) + || f.context().comments().has_trailing(*expression) + { + expression + .format() + .with_options(Parentheses::Preserve) + .fmt(f) + } + // Never parenthesize targets that come with their own parentheses, e.g. don't parenthesize lists or dictionary literals. + else if has_target_own_parentheses(expression, f.context()) { + expression.format().with_options(Parentheses::Never).fmt(f) + } else { + parenthesize_if_expands(&expression.format().with_options(Parentheses::Never)) + .fmt(f) + } + } + // Never parenthesize type params + AnyBeforeOperator::TypeParams(type_params) => type_params.format().fmt(f), + } + } +} + +/// Returns `true` for unsplittable expressions for which comments should be inlined. +fn should_inline_comments( + expression: &Expr, + parent: AnyNodeRef, + context: &PyFormatContext, +) -> bool { + match expression { + Expr::Name(_) | Expr::NoneLiteral(_) | Expr::NumberLiteral(_) | Expr::BooleanLiteral(_) => { + true + } + Expr::StringLiteral(string) => { + string.needs_parentheses(parent, context) == OptionalParentheses::BestFit + } + Expr::BytesLiteral(bytes) => { + bytes.needs_parentheses(parent, context) == OptionalParentheses::BestFit + } + Expr::FString(fstring) => { + fstring.needs_parentheses(parent, context) == OptionalParentheses::BestFit + } + _ => false, + } +} + +/// Tests whether an expression that for which comments shouldn't be inlined should use the best fit layout +fn should_non_inlineable_use_best_fit( + expr: &Expr, + parent: AnyNodeRef, + context: &PyFormatContext, +) -> bool { + match expr { + Expr::Attribute(attribute) => { + attribute.needs_parentheses(parent, context) == OptionalParentheses::BestFit + } + Expr::Call(call) => call.needs_parentheses(parent, context) == OptionalParentheses::BestFit, + _ => false, + } +} + +/// Returns `true` for targets that should not be parenthesized if they split because their expanded +/// layout comes with their own set of parentheses. +pub(super) fn has_target_own_parentheses(target: &Expr, context: &PyFormatContext) -> bool { + matches!(target, Expr::Tuple(_)) || has_own_parentheses(target, context).is_some() +} diff --git a/crates/ruff_python_formatter/src/statement/stmt_aug_assign.rs b/crates/ruff_python_formatter/src/statement/stmt_aug_assign.rs index 65260c5fecdc9..003c10a32a8e1 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_aug_assign.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_aug_assign.rs @@ -2,10 +2,13 @@ use ruff_formatter::write; use ruff_python_ast::StmtAugAssign; use crate::comments::{SourceComment, SuppressionKind}; - -use crate::expression::maybe_parenthesize_expression; -use crate::expression::parentheses::Parenthesize; +use crate::expression::parentheses::is_expression_parenthesized; use crate::prelude::*; +use crate::preview::is_prefer_splitting_right_hand_side_of_assignments_enabled; +use crate::statement::stmt_assign::{ + has_target_own_parentheses, AnyAssignmentOperator, AnyBeforeOperator, + FormatStatementsLastExpression, +}; use crate::statement::trailing_semicolon; use crate::{AsFormat, FormatNodeRule}; @@ -20,17 +23,35 @@ impl FormatNodeRule for FormatStmtAugAssign { value, range: _, } = item; - write!( - f, - [ - target.format(), - space(), - op.format(), - token("="), - space(), - maybe_parenthesize_expression(value, item, Parenthesize::IfBreaks) - ] - )?; + + if is_prefer_splitting_right_hand_side_of_assignments_enabled(f.context()) + && has_target_own_parentheses(target, f.context()) + && !is_expression_parenthesized( + target.into(), + f.context().comments().ranges(), + f.context().source(), + ) + { + FormatStatementsLastExpression::RightToLeft { + before_operator: AnyBeforeOperator::Expression(target), + operator: AnyAssignmentOperator::AugAssign(*op), + value, + statement: item.into(), + } + .fmt(f)?; + } else { + write!( + f, + [ + target.format(), + space(), + op.format(), + token("="), + space(), + FormatStatementsLastExpression::left_to_right(value, item) + ] + )?; + } if f.options().source_type().is_ipynb() && f.context().node_level().is_last_top_level_statement() diff --git a/crates/ruff_python_formatter/src/statement/stmt_return.rs b/crates/ruff_python_formatter/src/statement/stmt_return.rs index be63db2e73f2b..4eaa3d92613ab 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_return.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_return.rs @@ -3,9 +3,8 @@ use ruff_python_ast::{Expr, StmtReturn}; use crate::comments::{SourceComment, SuppressionKind}; use crate::expression::expr_tuple::TupleParentheses; -use crate::expression::maybe_parenthesize_expression; -use crate::expression::parentheses::Parenthesize; use crate::prelude::*; +use crate::statement::stmt_assign::FormatStatementsLastExpression; #[derive(Default)] pub struct FormatStmtReturn; @@ -33,7 +32,7 @@ impl FormatNodeRule for FormatStmtReturn { f, [ space(), - maybe_parenthesize_expression(value, item, Parenthesize::IfBreaks) + FormatStatementsLastExpression::left_to_right(value, item) ] ) } diff --git a/crates/ruff_python_formatter/src/statement/stmt_type_alias.rs b/crates/ruff_python_formatter/src/statement/stmt_type_alias.rs index c2daaf8528d20..b6ae69b4430af 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_type_alias.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_type_alias.rs @@ -2,9 +2,11 @@ use ruff_formatter::write; use ruff_python_ast::StmtTypeAlias; use crate::comments::{SourceComment, SuppressionKind}; -use crate::expression::maybe_parenthesize_expression; -use crate::expression::parentheses::Parenthesize; use crate::prelude::*; +use crate::preview::is_prefer_splitting_right_hand_side_of_assignments_enabled; +use crate::statement::stmt_assign::{ + AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression, +}; #[derive(Default)] pub struct FormatStmtTypeAlias; @@ -21,6 +23,16 @@ impl FormatNodeRule for FormatStmtTypeAlias { write!(f, [token("type"), space(), name.as_ref().format()])?; if let Some(type_params) = type_params { + if is_prefer_splitting_right_hand_side_of_assignments_enabled(f.context()) { + return FormatStatementsLastExpression::RightToLeft { + before_operator: AnyBeforeOperator::TypeParams(type_params), + operator: AnyAssignmentOperator::Assign, + value, + statement: item.into(), + } + .fmt(f); + }; + write!(f, [type_params.format()])?; } @@ -30,7 +42,7 @@ impl FormatNodeRule for FormatStmtTypeAlias { space(), token("="), space(), - maybe_parenthesize_expression(value, item, Parenthesize::IfBreaks) + FormatStatementsLastExpression::left_to_right(value, item) ] ) } diff --git a/crates/ruff_python_formatter/src/statement/stmt_with.rs b/crates/ruff_python_formatter/src/statement/stmt_with.rs index af2389279b559..06dc9a5f88f6b 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_with.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_with.rs @@ -6,9 +6,7 @@ use ruff_text_size::{Ranged, TextRange}; use crate::builders::parenthesize_if_expands; use crate::comments::SourceComment; -use crate::expression::parentheses::{ - in_parentheses_only_soft_line_break_or_space, optional_parentheses, parenthesized, -}; +use crate::expression::parentheses::parenthesized; use crate::other::commas; use crate::prelude::*; use crate::statement::clause::{clause_body, clause_header, ClauseHeader}; @@ -77,7 +75,7 @@ impl FormatNodeRule for FormatStmtWith { joiner.entry_with_line_separator( item, &item.format(), - in_parentheses_only_soft_line_break_or_space(), + soft_line_break_or_space(), ); } joiner.finish() @@ -87,7 +85,7 @@ impl FormatNodeRule for FormatStmtWith { // This is similar to `maybe_parenthesize_expression`, but we're not // dealing with an expression here, it's a `WithItem`. if comments.has_leading(item) || comments.has_trailing(item) { - optional_parentheses(&item.format()).fmt(f)?; + parenthesized("(", &item.format(), ")").fmt(f)?; } else { item.format().fmt(f)?; } diff --git a/crates/ruff_python_formatter/src/statement/suite.rs b/crates/ruff_python_formatter/src/statement/suite.rs index 65ed7faec11d5..8b3d9e1a5efbd 100644 --- a/crates/ruff_python_formatter/src/statement/suite.rs +++ b/crates/ruff_python_formatter/src/statement/suite.rs @@ -8,8 +8,8 @@ use ruff_text_size::{Ranged, TextRange}; use crate::comments::{ leading_comments, trailing_comments, Comments, LeadingDanglingTrailingComments, }; -use crate::context::{NodeLevel, TopLevelStatementPosition, WithNodeLevel}; -use crate::expression::string::StringLayout; +use crate::context::{NodeLevel, TopLevelStatementPosition, WithIndentLevel, WithNodeLevel}; +use crate::expression::expr_string_literal::ExprStringLiteralKind; use crate::prelude::*; use crate::statement::stmt_expr::FormatStmtExpr; use crate::verbatim::{ @@ -71,7 +71,8 @@ impl FormatRule> for FormatSuite { let source = f.context().source(); let source_type = f.options().source_type(); - let f = &mut WithNodeLevel::new(node_level, f); + let f = WithNodeLevel::new(node_level, f); + let f = &mut WithIndentLevel::new(f.context().indent_level().increment(), f); // Format the first statement in the body, which often has special formatting rules. let first = match self.kind { @@ -511,7 +512,9 @@ pub(crate) fn contains_only_an_ellipsis(body: &[Stmt], comments: &Comments) -> b let [node] = body else { return false; }; - value.is_ellipsis_literal_expr() && !comments.has_leading(node) + value.is_ellipsis_literal_expr() + && !comments.has_leading(node) + && !comments.has_trailing_own_line(node) } _ => false, } @@ -569,10 +572,14 @@ impl<'a> DocstringStmt<'a> { }; match value.as_ref() { - Expr::StringLiteral(value) if !value.implicit_concatenated => Some(DocstringStmt { - docstring: stmt, - suite_kind, - }), + Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) + if !value.is_implicit_concatenated() => + { + Some(DocstringStmt { + docstring: stmt, + suite_kind, + }) + } _ => None, } } @@ -602,7 +609,7 @@ impl Format> for DocstringStmt<'_> { leading_comments(node_comments.leading), string_literal .format() - .with_options(StringLayout::DocString), + .with_options(ExprStringLiteralKind::Docstring), ] )?; diff --git a/crates/ruff_python_formatter/src/string/docstring.rs b/crates/ruff_python_formatter/src/string/docstring.rs new file mode 100644 index 0000000000000..51fee063ca97e --- /dev/null +++ b/crates/ruff_python_formatter/src/string/docstring.rs @@ -0,0 +1,1635 @@ +// This gives tons of false positives in this file because of +// "reStructuredText." +#![allow(clippy::doc_markdown)] + +use std::{borrow::Cow, collections::VecDeque}; + +use {once_cell::sync::Lazy, regex::Regex}; + +use { + ruff_formatter::{write, FormatOptions, IndentStyle, LineWidth, Printed}, + ruff_python_trivia::{is_python_whitespace, PythonWhitespace}, + ruff_source_file::Locator, + ruff_text_size::{Ranged, TextLen, TextRange, TextSize}, +}; + +use crate::{prelude::*, DocstringCodeLineWidth, FormatModuleError}; + +use super::{NormalizedString, QuoteChar}; + +/// Format a docstring by trimming whitespace and adjusting the indentation. +/// +/// Summary of changes we make: +/// * Normalize the string like all other strings +/// * Ignore docstring that have an escaped newline +/// * Trim all trailing whitespace, except for a chaperone space that avoids quotes or backslashes +/// in the last line. +/// * Trim leading whitespace on the first line, again except for a chaperone space +/// * If there is only content in the first line and after that only whitespace, collapse the +/// docstring into one line +/// * Adjust the indentation (see below) +/// +/// # Docstring indentation +/// +/// Unlike any other string, like black we change the indentation of docstring lines. +/// +/// We want to preserve the indentation inside the docstring relative to the suite statement/block +/// indent that the docstring statement is in, but also want to apply the change of the outer +/// indentation in the docstring, e.g. +/// ```python +/// def sparkle_sky(): +/// """Make a pretty sparkly sky. +/// * * ✨ *. . +/// * * ✨ . +/// . * . ✨ * . . +/// """ +/// ``` +/// should become +/// ```python +/// def sparkle_sky(): +/// """Make a pretty sparkly sky. +/// * * ✨ *. . +/// * * ✨ . +/// . * . ✨ * . . +/// """ +/// ``` +/// We can't compute the full indentation here since we don't know what the block indent of +/// the doc comment will be yet and which we can only have added by formatting each line +/// separately with a hard line break. This means we need to strip shared indentation from +/// docstring while preserving the in-docstring bigger-than-suite-statement indentation. Example: +/// ```python +/// def f(): +/// """first line +/// line a +/// line b +/// """ +/// ``` +/// The docstring indentation is 2, the block indents will change this to 4 (but we can't +/// determine this at this point). The indentation of line a is 2, so we trim ` line a` +/// to `line a`. For line b it's 5, so we trim it to `line b` and pad with 5-2=3 spaces to +/// ` line b`. The closing quotes, being on their own line, are stripped get only the +/// default indentation. Fully formatted: +/// ```python +/// def f(): +/// """first line +/// line a +/// line b +/// """ +/// ``` +/// +/// Tabs are counted by padding them to the next multiple of 8 according to +/// [`str.expandtabs`](https://docs.python.org/3/library/stdtypes.html#str.expandtabs). When +/// we see indentation that contains a tab or any other none ascii-space whitespace we rewrite the +/// string. +/// +/// Additionally, if any line in the docstring has less indentation than the docstring +/// (effectively a negative indentation wrt. to the current level), we pad all lines to the +/// level of the docstring with spaces. +/// ```python +/// def f(): +/// """first line +/// line a +/// line b +/// line c +/// """ +/// ``` +/// Here line a is 3 columns negatively indented, so we pad all lines by an extra 3 spaces: +/// ```python +/// def f(): +/// """first line +/// line a +/// line b +/// line c +/// """ +/// ``` +pub(crate) fn format(normalized: &NormalizedString, f: &mut PyFormatter) -> FormatResult<()> { + let docstring = &normalized.text; + + // Black doesn't change the indentation of docstrings that contain an escaped newline + if contains_unescaped_newline(docstring) { + return normalized.fmt(f); + } + + // is_borrowed is unstable :/ + let already_normalized = matches!(docstring, Cow::Borrowed(_)); + + let mut lines = docstring.lines().peekable(); + + // Start the string + write!( + f, + [ + normalized.prefix, + normalized.quotes, + source_position(normalized.start()), + ] + )?; + // We track where in the source docstring we are (in source code byte offsets) + let mut offset = normalized.start(); + + // The first line directly after the opening quotes has different rules than the rest, mainly + // that we remove all leading whitespace as there's no indentation + let first = lines.next().unwrap_or_default(); + // Black trims whitespace using [`str.strip()`](https://docs.python.org/3/library/stdtypes.html#str.strip) + // https://github.com/psf/black/blob/b4dca26c7d93f930bbd5a7b552807370b60d4298/src/black/strings.py#L77-L85 + // So we use the unicode whitespace definition through `trim_{start,end}` instead of the python + // tokenizer whitespace definition in `trim_whitespace_{start,end}`. + let trim_end = first.trim_end(); + let trim_both = trim_end.trim_start(); + + // Edge case: The first line is `""" "content`, so we need to insert chaperone space that keep + // inner quotes and closing quotes from getting to close to avoid `""""content` + if trim_both.starts_with(normalized.quotes.quote_char.as_char()) { + space().fmt(f)?; + } + + if !trim_end.is_empty() { + // For the first line of the docstring we strip the leading and trailing whitespace, e.g. + // `""" content ` to `"""content` + let leading_whitespace = trim_end.text_len() - trim_both.text_len(); + let trimmed_line_range = + TextRange::at(offset, trim_end.text_len()).add_start(leading_whitespace); + if already_normalized { + source_text_slice(trimmed_line_range).fmt(f)?; + } else { + text(trim_both, Some(trimmed_line_range.start())).fmt(f)?; + } + } + offset += first.text_len(); + + // Check if we have a single line (or empty) docstring + if docstring[first.len()..].trim().is_empty() { + // For `"""\n"""` or other whitespace between the quotes, black keeps a single whitespace, + // but `""""""` doesn't get one inserted. + if needs_chaperone_space(normalized, trim_end) + || (trim_end.is_empty() && !docstring.is_empty()) + { + space().fmt(f)?; + } + normalized.quotes.fmt(f)?; + return Ok(()); + } + + hard_line_break().fmt(f)?; + // We know that the normalized string has \n line endings + offset += "\n".text_len(); + + // If some line of the docstring is less indented than the function body, we pad all lines to + // align it with the docstring statement. Conversely, if all lines are over-indented, we strip + // the extra indentation. We call this stripped indentation since it's relative to the block + // indent printer-made indentation. + let stripped_indentation_length = lines + .clone() + // We don't want to count whitespace-only lines as miss-indented + .filter(|line| !line.trim().is_empty()) + .map(indentation_length) + .min() + .unwrap_or_default(); + + DocstringLinePrinter { + f, + action_queue: VecDeque::new(), + offset, + stripped_indentation_length, + already_normalized, + quote_char: normalized.quotes.quote_char, + code_example: CodeExample::default(), + } + .add_iter(lines)?; + + // Same special case in the last line as for the first line + let trim_end = docstring + .as_ref() + .trim_end_matches(|c: char| c.is_whitespace() && c != '\n'); + if needs_chaperone_space(normalized, trim_end) { + space().fmt(f)?; + } + + write!(f, [source_position(normalized.end()), normalized.quotes]) +} + +fn contains_unescaped_newline(haystack: &str) -> bool { + let mut rest = haystack; + + while let Some(index) = memchr::memchr(b'\\', rest.as_bytes()) { + rest = &rest[index + 1..].trim_whitespace_start(); + + if rest.starts_with('\n') { + return true; + } + } + + false +} + +/// An abstraction for printing each line of a docstring. +struct DocstringLinePrinter<'ast, 'buf, 'fmt, 'src> { + f: &'fmt mut PyFormatter<'ast, 'buf>, + + /// A queue of actions to perform. + /// + /// Whenever we process a line, it is possible for it to generate multiple + /// actions to take. The most basic, and most common case, is for the line + /// to just simply be printed as-is. But in some cases, a line is part of + /// a code example that we'd like to reformat. In those cases, the actions + /// can be more complicated. + /// + /// Actions are pushed on to the end of the queue and popped from the + /// beginning. + action_queue: VecDeque>, + + /// The source offset of the beginning of the line that is currently being + /// printed. + offset: TextSize, + + /// Indentation alignment based on the least indented line in the + /// docstring. + stripped_indentation_length: TextSize, + + /// Whether the docstring is overall already considered normalized. When it + /// is, the formatter can take a fast path. + already_normalized: bool, + + /// The quote character used by the docstring being printed. + quote_char: QuoteChar, + + /// The current code example detected in the docstring. + code_example: CodeExample<'src>, +} + +impl<'ast, 'buf, 'fmt, 'src> DocstringLinePrinter<'ast, 'buf, 'fmt, 'src> { + /// Print all of the lines in the given iterator to this + /// printer's formatter. + /// + /// Note that callers may treat the first line specially, such that the + /// iterator given contains all lines except for the first. + fn add_iter( + &mut self, + mut lines: std::iter::Peekable>, + ) -> FormatResult<()> { + while let Some(line) = lines.next() { + let line = InputDocstringLine { + line, + offset: self.offset, + next: lines.peek().copied(), + }; + // We know that the normalized string has \n line endings. + self.offset += line.line.text_len() + "\n".text_len(); + self.add_one(line)?; + } + self.code_example.finish(&mut self.action_queue); + self.run_action_queue() + } + + /// Adds the given line to this printer. + /// + /// Depending on what's in the line, this may or may not print the line + /// immediately to the underlying buffer. If the line starts or is part + /// of an existing code snippet, then the lines will get buffered until + /// the code snippet is complete. + fn add_one(&mut self, line: InputDocstringLine<'src>) -> FormatResult<()> { + // Just pass through the line as-is without looking for a code snippet + // when docstring code formatting is disabled. And also when we are + // formatting a code snippet so as to avoid arbitrarily nested code + // snippet formatting. We avoid this because it's likely quite tricky + // to get right 100% of the time, although perhaps not impossible. It's + // not clear that it's worth the effort to support. + if !self.f.options().docstring_code().is_enabled() || self.f.context().docstring().is_some() + { + return self.print_one(&line.as_output()); + } + self.code_example.add(line, &mut self.action_queue); + self.run_action_queue() + } + + /// Process any actions in this printer's queue until the queue is empty. + fn run_action_queue(&mut self) -> FormatResult<()> { + while let Some(action) = self.action_queue.pop_front() { + match action { + CodeExampleAddAction::Print { original } => { + self.print_one(&original.as_output())?; + } + CodeExampleAddAction::Kept => {} + CodeExampleAddAction::Reset { code } => { + for codeline in code { + self.print_one(&codeline.original.as_output())?; + } + } + CodeExampleAddAction::Format { mut kind } => { + let Some(formatted_lines) = self.format(&mut kind)? else { + // Since we've failed to emit these lines, we need to + // put them back in the queue but have them jump to the + // front of the queue to get processed before any other + // action. + self.action_queue.push_front(CodeExampleAddAction::Reset { + code: kind.into_code(), + }); + continue; + }; + + self.already_normalized = false; + match kind { + CodeExampleKind::Doctest(CodeExampleDoctest { ps1_indent, .. }) => { + let mut lines = formatted_lines.into_iter(); + let Some(first) = lines.next() else { continue }; + self.print_one( + &first.map(|line| std::format!("{ps1_indent}>>> {line}")), + )?; + for docline in lines { + self.print_one( + &docline.map(|line| std::format!("{ps1_indent}... {line}")), + )?; + } + } + CodeExampleKind::Rst(litblock) => { + let Some(min_indent) = litblock.min_indent else { + continue; + }; + // This looks suspicious, but it's consistent with the whitespace + // normalization that will occur anyway. + let indent = " ".repeat(min_indent.to_usize()); + for docline in formatted_lines { + self.print_one( + &docline.map(|line| std::format!("{indent}{line}")), + )?; + } + } + CodeExampleKind::Markdown(fenced) => { + // This looks suspicious, but it's consistent with the whitespace + // normalization that will occur anyway. + let indent = " ".repeat(fenced.opening_fence_indent.to_usize()); + for docline in formatted_lines { + self.print_one( + &docline.map(|line| std::format!("{indent}{line}")), + )?; + } + } + } + } + } + } + Ok(()) + } + + /// Prints the single line given. + /// + /// This mostly just handles indentation and ensuring line breaks are + /// inserted as appropriate before passing it on to the formatter to + /// print to the buffer. + fn print_one(&mut self, line: &OutputDocstringLine<'_>) -> FormatResult<()> { + let trim_end = line.line.trim_end(); + if trim_end.is_empty() { + return if line.is_last { + // If the doc string ends with ` """`, the last line is + // ` `, but we don't want to insert an empty line (but close + // the docstring). + Ok(()) + } else { + empty_line().fmt(self.f) + }; + } + + let tab_or_non_ascii_space = trim_end + .chars() + .take_while(|c| c.is_whitespace()) + .any(|c| c != ' '); + + if tab_or_non_ascii_space { + // We strip the indentation that is shared with the docstring + // statement, unless a line was indented less than the docstring + // statement, in which case we strip only this much indentation to + // implicitly pad all lines by the difference, or all lines were + // overindented, in which case we strip the additional whitespace + // (see example in [`format_docstring`] doc comment). We then + // prepend the in-docstring indentation to the string. + let indent_len = indentation_length(trim_end) - self.stripped_indentation_length; + let in_docstring_indent = " ".repeat(usize::from(indent_len)) + trim_end.trim_start(); + text(&in_docstring_indent, Some(line.offset)).fmt(self.f)?; + } else { + // Take the string with the trailing whitespace removed, then also + // skip the leading whitespace. + let trimmed_line_range = TextRange::at(line.offset, trim_end.text_len()) + .add_start(self.stripped_indentation_length); + if self.already_normalized { + source_text_slice(trimmed_line_range).fmt(self.f)?; + } else { + // All indents are ascii spaces, so the slicing is correct. + text( + &trim_end[usize::from(self.stripped_indentation_length)..], + Some(trimmed_line_range.start()), + ) + .fmt(self.f)?; + } + } + + // We handled the case that the closing quotes are on their own line + // above (the last line is empty except for whitespace). If they are on + // the same line as content, we don't insert a line break. + if !line.is_last { + hard_line_break().fmt(self.f)?; + } + + Ok(()) + } + + /// Given a code example, format them and return + /// the formatted code as a sequence of owned docstring lines. + /// + /// This may mutate the code example in place if extracting the lines of + /// code requires adjusting which part of each line is used for the actual + /// code bit. + /// + /// This routine generally only returns an error when the recursive call + /// to the formatter itself returns a `FormatError`. In all other cases + /// (for example, if the code snippet is invalid Python or even if the + /// resulting reformatted code snippet is invalid Python), then `Ok(None)` + /// is returned. In this case, callers should assume that a reformatted + /// code snippet is unavailable and bail out of trying to format it. + /// + /// Currently, when the above cases happen and `Ok(None)` is returned, the + /// routine is silent about it. So from the user's perspective, this will + /// fail silently. Ideally, this would at least emit a warning message, + /// but at time of writing, it wasn't clear to me how to best do that. + fn format( + &mut self, + kind: &mut CodeExampleKind<'_>, + ) -> FormatResult>>> { + use ruff_python_parser::AsMode; + + let line_width = match self.f.options().docstring_code_line_width() { + DocstringCodeLineWidth::Fixed(width) => width, + DocstringCodeLineWidth::Dynamic => { + let global_line_width = self.f.options().line_width().value(); + let indent_width = self.f.options().indent_width(); + let indent_level = self.f.context().indent_level(); + let current_indent = indent_level + .to_ascii_spaces(indent_width) + .saturating_add(kind.extra_indent_ascii_spaces()); + let width = std::cmp::max(1, global_line_width.saturating_sub(current_indent)); + LineWidth::try_from(width).expect("width is capped at a minimum of 1") + } + }; + + let code = kind.code(); + let (Some(unformatted_first), Some(unformatted_last)) = (code.first(), code.last()) else { + return Ok(None); + }; + let codeblob = code + .iter() + .map(|line| line.code) + .collect::>() + .join("\n"); + let options = self + .f + .options() + .clone() + .with_line_width(line_width) + // It's perhaps a little odd to be hard-coding the indent + // style here, but I believe it is necessary as a result + // of the whitespace normalization otherwise done in + // docstrings. Namely, tabs are rewritten with ASCII + // spaces. If code examples in docstrings are formatted + // with tabs and those tabs end up getting rewritten, this + // winds up screwing with the indentation in ways that + // results in formatting no longer being idempotent. Since + // tabs will get erased anyway, we just clobber them here + // instead of later, and as a result, get more consistent + // results. + .with_indent_style(IndentStyle::Space); + let printed = match docstring_format_source(options, self.quote_char, &codeblob) { + Ok(printed) => printed, + Err(FormatModuleError::FormatError(err)) => return Err(err), + Err( + FormatModuleError::LexError(_) + | FormatModuleError::ParseError(_) + | FormatModuleError::PrintError(_), + ) => { + return Ok(None); + } + }; + // This is a little hokey, but we want to determine whether the + // reformatted code snippet will lead to an overall invalid docstring. + // So attempt to parse it as Python code, but ensure it is wrapped + // within a docstring using the same quotes as the docstring we're in + // right now. + // + // This is an unfortunate stop-gap to attempt to prevent us from + // writing invalid Python due to some oddity of the code snippet within + // a docstring. As we fix corner cases over time, we can perhaps + // remove this check. See the `doctest_invalid_skipped` tests in + // `docstring_code_examples.py` for when this check is relevant. + let wrapped = match self.quote_char { + QuoteChar::Single => std::format!("'''{}'''", printed.as_code()), + QuoteChar::Double => { + std::format!(r#""""{}""""#, printed.as_code()) + } + }; + let result = ruff_python_parser::parse( + &wrapped, + self.f.options().source_type().as_mode(), + "", + ); + // If the resulting code is not valid, then reset and pass through + // the docstring lines as-is. + if result.is_err() { + return Ok(None); + } + let mut lines = printed + .as_code() + .lines() + .map(|line| OutputDocstringLine { + line: Cow::Owned(line.to_string()), + offset: unformatted_first.original.offset, + is_last: false, + }) + .collect::>(); + if let Some(reformatted_last) = lines.last_mut() { + reformatted_last.is_last = unformatted_last.original.is_last(); + } + Ok(Some(lines)) + } +} + +/// Represents a single line in a docstring. +/// +/// This type is only used to represent the original lines in a docstring. +/// Specifically, the line contained in this type has no changes from the input +/// source. +#[derive(Clone, Copy, Debug)] +struct InputDocstringLine<'src> { + /// The actual text of the line, not including the line terminator. + /// + /// In practice, this line is borrowed when it corresponds to an original + /// unformatted line in a docstring, and owned when it corresponds to a + /// reformatted line (e.g., from a code snippet) in a docstring. + line: &'src str, + + /// The offset into the source document which this line corresponds to. + offset: TextSize, + + /// For any input line that isn't the last line, this contains a reference + /// to the line immediately following this one. + /// + /// This is `None` if and only if this is the last line in the docstring. + next: Option<&'src str>, +} + +impl<'src> InputDocstringLine<'src> { + /// Borrow this input docstring line as an output docstring line. + fn as_output(&self) -> OutputDocstringLine<'src> { + OutputDocstringLine { + line: Cow::Borrowed(self.line), + offset: self.offset, + is_last: self.is_last(), + } + } + + /// Whether this is the last line in the docstring or not. + fn is_last(&self) -> bool { + self.next.is_none() + } +} + +/// Represents a single reformatted code line in a docstring. +/// +/// An input source line may be cheaply converted to an output source line. +/// This is the common case: an input source line is printed pretty much as it +/// is, with perhaps some whitespace normalization applied. The less common +/// case is that the output docstring line owns its `line` because it was +/// produced by reformatting a code snippet. +#[derive(Clone, Debug)] +struct OutputDocstringLine<'src> { + /// The output line. + /// + /// This is an owned variant in precisely the cases where it corresponds to + /// a line from a reformatted code snippet. In other cases, it is borrowed + /// from the input docstring line as-is. + line: Cow<'src, str>, + + /// The offset into the source document which this line corresponds to. + /// Currently, this is an estimate. + offset: TextSize, + + /// Whether this is the last line in a docstring or not. This is determined + /// by whether the last line in the code snippet was also the last line in + /// the docstring. If it was, then it follows that the last line in the + /// reformatted code snippet is also the last line in the docstring. + is_last: bool, +} + +impl<'src> OutputDocstringLine<'src> { + /// Return this reformatted line, but with the given function applied to + /// the text of the line. + fn map(self, mut map: impl FnMut(&str) -> String) -> OutputDocstringLine<'static> { + OutputDocstringLine { + line: Cow::Owned(map(&self.line)), + ..self + } + } +} + +/// A single code example extracted from a docstring. +/// +/// This represents an intermediate state from when the code example was first +/// found all the way up until the point at which the code example has finished +/// and is reformatted. +/// +/// Its default state is "empty." That is, that no code example is currently +/// being collected. +#[derive(Debug, Default)] +struct CodeExample<'src> { + /// The kind of code example being collected, or `None` if no code example + /// has been observed. + /// + /// The kind is split out into a separate type so that we can pass it + /// around and have a guarantee that a code example actually exists. + kind: Option>, +} + +impl<'src> CodeExample<'src> { + /// Attempt to add an original line from a docstring to this code example. + /// + /// Based on the line and the internal state of whether a code example is + /// currently being collected or not, this will push an "action" to the + /// given queue for the caller to perform. The typical case is a "print" + /// action, which instructs the caller to just print the line as though it + /// were not part of a code snippet. + fn add( + &mut self, + original: InputDocstringLine<'src>, + queue: &mut VecDeque>, + ) { + match self.kind.take() { + // There's no existing code example being built, so we look for + // the start of one or otherwise tell the caller we couldn't find + // anything. + None => { + self.add_start(original, queue); + } + Some(CodeExampleKind::Doctest(doctest)) => { + let Some(doctest) = doctest.add_code_line(original, queue) else { + self.add_start(original, queue); + return; + }; + self.kind = Some(CodeExampleKind::Doctest(doctest)); + } + Some(CodeExampleKind::Rst(litblock)) => { + let Some(litblock) = litblock.add_code_line(original, queue) else { + self.add_start(original, queue); + return; + }; + self.kind = Some(CodeExampleKind::Rst(litblock)); + } + Some(CodeExampleKind::Markdown(fenced)) => { + let Some(fenced) = fenced.add_code_line(original, queue) else { + // For Markdown, the last line in a block should be printed + // as-is. Especially since the last line in many Markdown + // fenced code blocks is identical to the start of a code + // block. So if we try to start a new code block with + // the last line, we risk opening another Markdown block + // inappropriately. + return; + }; + self.kind = Some(CodeExampleKind::Markdown(fenced)); + } + } + } + + /// Finish the code example by generating any final actions if applicable. + /// + /// This typically adds an action when the end of a code example coincides + /// with the end of the docstring. + fn finish(&mut self, queue: &mut VecDeque>) { + let Some(kind) = self.kind.take() else { return }; + queue.push_back(CodeExampleAddAction::Format { kind }); + } + + /// Looks for the start of a code example. If one was found, then the given + /// line is kept and added as part of the code example. Otherwise, the line + /// is pushed onto the queue unchanged to be printed as-is. + /// + /// # Panics + /// + /// This panics when the existing code-example is any non-None value. That + /// is, this routine assumes that there is no ongoing code example being + /// collected and looks for the beginning of another code example. + fn add_start( + &mut self, + original: InputDocstringLine<'src>, + queue: &mut VecDeque>, + ) { + assert!(self.kind.is_none(), "expected no existing code example"); + if let Some(doctest) = CodeExampleDoctest::new(original) { + self.kind = Some(CodeExampleKind::Doctest(doctest)); + queue.push_back(CodeExampleAddAction::Kept); + } else if let Some(litblock) = CodeExampleRst::new(original) { + self.kind = Some(CodeExampleKind::Rst(litblock)); + queue.push_back(CodeExampleAddAction::Print { original }); + } else if let Some(fenced) = CodeExampleMarkdown::new(original) { + self.kind = Some(CodeExampleKind::Markdown(fenced)); + queue.push_back(CodeExampleAddAction::Print { original }); + } else { + queue.push_back(CodeExampleAddAction::Print { original }); + } + } +} + +/// The kind of code example observed in a docstring. +#[derive(Debug)] +enum CodeExampleKind<'src> { + /// Code found in Python "doctests." + /// + /// Documentation describing doctests and how they're recognized can be + /// found as part of the Python standard library: + /// https://docs.python.org/3/library/doctest.html. + /// + /// (You'll likely need to read the [regex matching] used internally by the + /// doctest module to determine more precisely how it works.) + /// + /// [regex matching]: https://github.com/python/cpython/blob/0ff6368519ed7542ad8b443de01108690102420a/Lib/doctest.py#L611-L622 + Doctest(CodeExampleDoctest<'src>), + /// Code found from a reStructuredText "[literal block]" or "[code block + /// directive]". + /// + /// [literal block]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks + /// [code block directive]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block + Rst(CodeExampleRst<'src>), + /// Code found from a Markdown "[fenced code block]". + /// + /// [fenced code block]: https://spec.commonmark.org/0.30/#fenced-code-blocks + Markdown(CodeExampleMarkdown<'src>), +} + +impl<'src> CodeExampleKind<'src> { + /// Return the lines of code collected so far for this example. + /// + /// This is borrowed mutably because it may need to mutate the code lines + /// based on the state accrued so far. + fn code(&mut self) -> &[CodeExampleLine<'src>] { + match *self { + CodeExampleKind::Doctest(ref doctest) => &doctest.lines, + CodeExampleKind::Rst(ref mut litblock) => litblock.indented_code(), + CodeExampleKind::Markdown(ref fenced) => &fenced.lines, + } + } + + /// Consume this code example and return only the lines that have been + /// accrued so far. + /// + /// This is useful when the code example being collected has been + /// determined to be invalid, and one wants to "give up" and print the + /// original lines through unchanged without attempting formatting. + fn into_code(self) -> Vec> { + match self { + CodeExampleKind::Doctest(doctest) => doctest.lines, + CodeExampleKind::Rst(litblock) => litblock.lines, + CodeExampleKind::Markdown(fenced) => fenced.lines, + } + } + + /// This returns any extra indent that will be added after formatting this + /// code example. + /// + /// The extra indent is expressed in units of ASCII space characters. + fn extra_indent_ascii_spaces(&self) -> u16 { + match *self { + CodeExampleKind::Doctest(_) => 4, + _ => 0, + } + } +} + +/// State corresponding to a single doctest code example found in a docstring. +#[derive(Debug)] +struct CodeExampleDoctest<'src> { + /// The lines that have been seen so far that make up the doctest. + lines: Vec>, + + /// The indent observed in the first doctest line. + /// + /// More precisely, this corresponds to the whitespace observed before + /// the starting `>>> ` (the "PS1 prompt"). + ps1_indent: &'src str, +} + +impl<'src> CodeExampleDoctest<'src> { + /// Looks for a valid doctest PS1 prompt in the line given. + /// + /// If one was found, then state for a new doctest code example is + /// returned, along with the code example line. + fn new(original: InputDocstringLine<'src>) -> Option> { + let trim_start = original.line.trim_start(); + // Prompts must be followed by an ASCII space character[1]. + // + // [1]: https://github.com/python/cpython/blob/0ff6368519ed7542ad8b443de01108690102420a/Lib/doctest.py#L809-L812 + let code = trim_start.strip_prefix(">>> ")?; + let indent_len = original + .line + .len() + .checked_sub(trim_start.len()) + .expect("suffix is <= original"); + let lines = vec![CodeExampleLine { original, code }]; + let ps1_indent = &original.line[..indent_len]; + let doctest = CodeExampleDoctest { lines, ps1_indent }; + Some(doctest) + } + + /// Looks for a valid doctest PS2 prompt in the line given. If one is + /// found, it is added to this code example and ownership of the example is + /// returned to the caller. In this case, callers should continue trying to + /// add PS2 prompt lines. + /// + /// But if one isn't found, then the given line is not part of the code + /// example and ownership of this example is not returned. + /// + /// In either case, relevant actions will be added to the given queue to + /// process. + fn add_code_line( + mut self, + original: InputDocstringLine<'src>, + queue: &mut VecDeque>, + ) -> Option> { + let Some((ps2_indent, ps2_after)) = original.line.split_once("...") else { + queue.push_back(self.into_format_action()); + return None; + }; + // PS2 prompts must have the same indentation as their + // corresponding PS1 prompt.[1] While the 'doctest' Python + // module will error in this case, we just treat this line as a + // non-doctest line. + // + // [1]: https://github.com/python/cpython/blob/0ff6368519ed7542ad8b443de01108690102420a/Lib/doctest.py#L733 + if self.ps1_indent != ps2_indent { + queue.push_back(self.into_format_action()); + return None; + } + // PS2 prompts must be followed by an ASCII space character unless + // it's an otherwise empty line[1]. + // + // [1]: https://github.com/python/cpython/blob/0ff6368519ed7542ad8b443de01108690102420a/Lib/doctest.py#L809-L812 + let code = match ps2_after.strip_prefix(' ') { + None if ps2_after.is_empty() => "", + None => { + queue.push_back(self.into_format_action()); + return None; + } + Some(code) => code, + }; + self.lines.push(CodeExampleLine { original, code }); + queue.push_back(CodeExampleAddAction::Kept); + Some(self) + } + + /// Consume this doctest and turn it into a formatting action. + fn into_format_action(self) -> CodeExampleAddAction<'src> { + CodeExampleAddAction::Format { + kind: CodeExampleKind::Doctest(self), + } + } +} + +/// State corresponding to a single reStructuredText literal block or +/// code-block directive. +/// +/// While a literal block and code-block directive are technically two +/// different reStructuredText constructs, we use one type to represent +/// both because they are exceptionally similar. Basically, they are +/// the same with two main differences: +/// +/// 1. Literal blocks are began with a line that ends with `::`. Code block +/// directives are began with a line like `.. code-block:: python`. +/// 2. Code block directives permit a list of options as a "field list" +/// immediately after the opening line. Literal blocks have no options. +/// +/// Otherwise, everything else, including the indentation structure, is the +/// same. +#[derive(Debug)] +struct CodeExampleRst<'src> { + /// The lines that have been seen so far that make up the block. + lines: Vec>, + + /// The indent of the line "opening" this block measured via + /// `indentation_length`. + /// + /// It can either be the indent of a line ending with `::` (for a literal + /// block) or the indent of a line starting with `.. ` (a directive). + /// + /// The content body of a block needs to be indented more than the line + /// opening the block, so we use this indentation to look for indentation + /// that is "more than" it. + opening_indent: TextSize, + + /// The minimum indent of the block measured via `indentation_length`. + /// + /// This is `None` until the first such line is seen. If no such line is + /// found, then we consider it an invalid block and bail out of trying to + /// find a code snippet. Otherwise, we update this indentation as we see + /// lines in the block with less indentation. (Usually, the minimum is the + /// indentation of the first block, but this is not required.) + /// + /// By construction, all lines part of the block must have at least this + /// indentation. Additionally, it is guaranteed that the indentation length + /// of the opening indent is strictly less than the indentation of the + /// minimum indent. Namely, the block ends once we find a line that has + /// been unindented to at most the indent of the opening line. + /// + /// When the code snippet has been extracted, it is re-built before being + /// reformatted. The minimum indent is stripped from each line when it is + /// re-built. + min_indent: Option, + + /// Whether this is a directive block or not. When not a directive, this is + /// a literal block. The main difference between them is that they start + /// differently. A literal block is started merely by trailing a line with + /// `::`. A directive block is started with `.. code-block:: python`. + /// + /// The other difference is that directive blocks can have options + /// (represented as a reStructuredText "field list") after the beginning of + /// the directive and before the body content of the directive. + is_directive: bool, +} + +impl<'src> CodeExampleRst<'src> { + /// Looks for the start of a reStructuredText [literal block] or [code + /// block directive]. + /// + /// If the start of a block is found, then this returns a correctly + /// initialized reStructuredText block. Callers should print the line as + /// given as it is not retained as part of the block. + /// + /// [literal block]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks + /// [code block directive]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block + fn new(original: InputDocstringLine<'src>) -> Option { + let (opening_indent, rest) = indent_with_suffix(original.line); + if rest.starts_with(".. ") { + if let Some(litblock) = CodeExampleRst::new_code_block(original) { + return Some(litblock); + } + // In theory, we could still have something that looks like a literal block, + // but if the line starts with `.. `, then it seems like it probably shouldn't + // be a literal block. For example: + // + // .. code-block:: + // + // cool_stuff( 1 ) + // + // The above is not valid because the `language` argument is missing from + // the `code-block` directive. Because of how we handle it here, the above + // is not treated as a code snippet. + return None; + } + // At this point, we know we didn't find a code block, so the only + // thing we can hope for is a literal block which must end with a `::`. + if !rest.trim_end().ends_with("::") { + return None; + } + Some(CodeExampleRst { + lines: vec![], + opening_indent: indentation_length(opening_indent), + min_indent: None, + is_directive: false, + }) + } + + /// Attempts to create a new reStructuredText code example from a + /// `code-block` or `sourcecode` directive. If one couldn't be found, then + /// `None` is returned. + fn new_code_block(original: InputDocstringLine<'src>) -> Option { + // This regex attempts to parse the start of a reStructuredText code + // block [directive]. From the reStructuredText spec: + // + // > Directives are indicated by an explicit markup start (".. ") + // > followed by the directive type, two colons, and whitespace + // > (together called the "directive marker"). Directive types + // > are case-insensitive single words (alphanumerics plus + // > isolated internal hyphens, underscores, plus signs, colons, + // > and periods; no whitespace). + // + // The language names matched here (e.g., `python` or `py`) are taken + // from the [Pygments lexer names], which is referenced from the docs + // for the [code-block] directive. + // + // [directives]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#directives + // [Pygments lexer names]: https://pygments.org/docs/lexers/ + // [code-block]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block + static DIRECTIVE_START: Lazy = Lazy::new(|| { + Regex::new( + r"(?m)^\s*\.\. \s*(?i:code-block|sourcecode)::\s*(?i:python|py|python3|py3)$", + ) + .unwrap() + }); + if !DIRECTIVE_START.is_match(original.line) { + return None; + } + Some(CodeExampleRst { + lines: vec![], + opening_indent: indentation_length(original.line), + min_indent: None, + is_directive: true, + }) + } + + /// Returns the code collected in this example as a sequence of lines. + /// + /// The lines returned have the minimum indentation stripped from their + /// prefix in-place. Based on the definition of minimum indentation, this + /// implies there is at least one line in the slice returned with no + /// whitespace prefix. + fn indented_code(&mut self) -> &[CodeExampleLine<'src>] { + let Some(min_indent) = self.min_indent else { + return &[]; + }; + for line in &mut self.lines { + line.code = if line.original.line.trim().is_empty() { + "" + } else { + indentation_trim(min_indent, line.original.line) + }; + } + &self.lines + } + + /// Attempts to add the given line from a docstring to the reStructuredText + /// code snippet being collected. + /// + /// This takes ownership of `self`, and if ownership is returned to the + /// caller, that means the caller should continue trying to add lines to + /// this code snippet. Otherwise, if ownership is not returned, then this + /// implies at least one action was added to the give queue to either reset + /// the code block or format. That is, the code snippet was either found to + /// be invalid or it was completed and should be reformatted. + /// + /// Note that actions may be added even if ownership is returned. For + /// example, empty lines immediately preceding the actual code snippet will + /// be returned back as an action to print them verbatim, but the caller + /// should still continue to try to add lines to this code snippet. + fn add_code_line( + mut self, + original: InputDocstringLine<'src>, + queue: &mut VecDeque>, + ) -> Option> { + // If we haven't started populating the minimum indent yet, then + // we haven't found the first code line and may need to find and + // pass through leading empty lines. + let Some(min_indent) = self.min_indent else { + return self.add_first_line(original, queue); + }; + let (indent, rest) = indent_with_suffix(original.line); + if rest.is_empty() { + // This is the standard way we close a block: when we see + // an empty line followed by an unindented non-empty line. + if let Some(next) = original.next { + let (next_indent, next_rest) = indent_with_suffix(next); + if !next_rest.is_empty() && indentation_length(next_indent) <= self.opening_indent { + self.push_format_action(queue); + return None; + } + } else { + self.push_format_action(queue); + return None; + } + self.push(original); + queue.push_back(CodeExampleAddAction::Kept); + return Some(self); + } + let indent_len = indentation_length(indent); + if indent_len <= self.opening_indent { + // If we find an unindented non-empty line at the same (or less) + // indentation of the opening line at this point, then we know it + // must be wrong because we didn't see it immediately following an + // empty line. + queue.push_back(self.into_reset_action()); + return None; + } else if indent_len < min_indent { + // While the minimum indent is usually the indentation of the first + // line in a code snippet, it is not guaranteed to be the case. + // And indeed, reST is happy to let blocks have a first line whose + // indentation is greater than a subsequent line in the block. The + // only real restriction is that every line in the block must be + // indented at least past the indentation of the `::` line. + self.min_indent = Some(indent_len); + } + self.push(original); + queue.push_back(CodeExampleAddAction::Kept); + Some(self) + } + + /// Looks for the first line in a literal or code block. + /// + /// If a first line is found, then this returns true. Otherwise, an empty + /// line has been found and the caller should pass it through to the + /// docstring unchanged. (Empty lines are allowed to precede a + /// block. And there must be at least one of them.) + /// + /// If the given line is invalid for a reStructuredText block (i.e., no + /// empty lines seen between the opening line), then an error variant is + /// returned. In this case, callers should bail out of parsing this code + /// example. + /// + /// When this returns `true`, it is guaranteed that `self.min_indent` is + /// set to a non-None value. + /// + /// # Panics + /// + /// Callers must only call this when the first indentation has not yet been + /// found. If it has, then this panics. + fn add_first_line( + mut self, + original: InputDocstringLine<'src>, + queue: &mut VecDeque>, + ) -> Option> { + assert!(self.min_indent.is_none()); + + // While the rst spec isn't completely clear on this point, through + // experimentation, I found that multiple empty lines before the first + // non-empty line are ignored. + let (indent, rest) = indent_with_suffix(original.line); + if rest.is_empty() { + queue.push_back(CodeExampleAddAction::Print { original }); + return Some(self); + } + // Ignore parameters in field lists. These can only occur in + // directives, not literal blocks. + if self.is_directive && is_rst_option(rest) { + queue.push_back(CodeExampleAddAction::Print { original }); + return Some(self); + } + let min_indent = indentation_length(indent); + // At this point, we found a non-empty line. The only thing we require + // is that its indentation is strictly greater than the indentation of + // the line containing the `::`. Otherwise, we treat this as an invalid + // block and bail. + if min_indent <= self.opening_indent { + queue.push_back(self.into_reset_action()); + return None; + } + self.min_indent = Some(min_indent); + self.push(original); + queue.push_back(CodeExampleAddAction::Kept); + Some(self) + } + + /// Pushes the given line as part of this code example. + fn push(&mut self, original: InputDocstringLine<'src>) { + // N.B. We record the code portion as identical to the original line. + // When we go to reformat the code lines, we change them by removing + // the `min_indent`. This design is necessary because the true value of + // `min_indent` isn't known until the entire block has been parsed. + let code = original.line; + self.lines.push(CodeExampleLine { original, code }); + } + + /// Consume this block and add actions to the give queue for formatting. + /// + /// This may trim lines from the end of the block and add them to the queue + /// for printing as-is. For example, this happens when there are trailing + /// empty lines, as we would like to preserve those since they aren't + /// generally treated as part of the code block. + fn push_format_action(mut self, queue: &mut VecDeque>) { + let has_non_whitespace = |line: &CodeExampleLine| { + line.original + .line + .chars() + .any(|ch| !is_python_whitespace(ch)) + }; + let first_trailing_empty_line = self + .lines + .iter() + .rposition(has_non_whitespace) + .map_or(0, |i| i + 1); + let trailing_lines = self.lines.split_off(first_trailing_empty_line); + queue.push_back(CodeExampleAddAction::Format { + kind: CodeExampleKind::Rst(self), + }); + queue.extend( + trailing_lines + .into_iter() + .map(|line| CodeExampleAddAction::Print { + original: line.original, + }), + ); + } + + /// Consume this block and turn it into a reset action. + /// + /// This occurs when we started collecting a code example from something + /// that looked like a block, but later determined that it wasn't a valid + /// block. + fn into_reset_action(self) -> CodeExampleAddAction<'src> { + CodeExampleAddAction::Reset { code: self.lines } + } +} + +/// Represents a code example extracted from a Markdown [fenced code block]. +/// +/// [fenced code block]: https://spec.commonmark.org/0.30/#fenced-code-blocks +#[derive(Debug)] +struct CodeExampleMarkdown<'src> { + /// The lines that have been seen so far that make up the block. + lines: Vec>, + + /// The indent of the line "opening" fence of this block measured via + /// `indentation_length`. + /// + /// This indentation is trimmed from the indentation of every line in the + /// body of the code block, + opening_fence_indent: TextSize, + + /// The kind of fence, backticks or tildes, used for this block. We need to + /// keep track of which kind was used to open the block in order to look + /// for a correct close of the block. + fence_kind: MarkdownFenceKind, + + /// The size of the fence, in codepoints, in the opening line. A correct + /// close of the fence must use *at least* this many characters. In other + /// words, this is the number of backticks or tildes that opened the fenced + /// code block. + fence_len: usize, +} + +impl<'src> CodeExampleMarkdown<'src> { + /// Looks for the start of a Markdown [fenced code block]. + /// + /// If the start of a block is found, then this returns a correctly + /// initialized Markdown code block. Callers should print the line as given + /// as it is not retained as part of the block. + /// + /// [fenced code block]: https://spec.commonmark.org/0.30/#fenced-code-blocks + fn new(original: InputDocstringLine<'src>) -> Option> { + static FENCE_START: Lazy = Lazy::new(|| { + Regex::new( + r"(?xm) + ^ + (?: + # In the backtick case, info strings (following the fence) + # cannot contain backticks themselves, since it would + # introduce ambiguity with parsing inline code. In other + # words, if we didn't specifically exclude matching ` + # in the info string for backtick fences, then we might + # erroneously consider something to be a code fence block + # that is actually inline code. + # + # NOTE: The `ticklang` and `tildlang` capture groups are + # currently unused, but there was some discussion about not + # assuming unlabeled blocks were Python. At the time of + # writing, we do assume unlabeled blocks are Python, but + # one could inspect the `ticklang` and `tildlang` capture + # groups to determine whether the block is labeled or not. + (?```+)(?:\s*(?(?i:python|py|python3|py3))[^`]*)? + | + (?~~~+)(?:\s*(?(?i:python|py|python3|py3))\p{any}*)? + ) + $ + ", + ) + .unwrap() + }); + + let (opening_fence_indent, rest) = indent_with_suffix(original.line); + // Quit quickly in the vast majority of cases. + if !rest.starts_with("```") && !rest.starts_with("~~~") { + return None; + } + + let caps = FENCE_START.captures(rest)?; + let (fence_kind, fence_len) = if let Some(ticks) = caps.name("ticks") { + (MarkdownFenceKind::Backtick, ticks.as_str().chars().count()) + } else { + let tildes = caps + .name("tilds") + .expect("no ticks means it must be tildes"); + (MarkdownFenceKind::Tilde, tildes.as_str().chars().count()) + }; + Some(CodeExampleMarkdown { + lines: vec![], + opening_fence_indent: indentation_length(opening_fence_indent), + fence_kind, + fence_len, + }) + } + + /// Attempts to add the given line from a docstring to the Markdown code + /// snippet being collected. + /// + /// In this case, ownership is only not returned when the end of the block + /// was found, or if the block was determined to be invalid. A formatting + /// action is then pushed onto the queue. + fn add_code_line( + mut self, + original: InputDocstringLine<'src>, + queue: &mut VecDeque>, + ) -> Option> { + if self.is_end(original) { + queue.push_back(self.into_format_action()); + queue.push_back(CodeExampleAddAction::Print { original }); + return None; + } + // When a line in a Markdown fenced closed block is indented *less* + // than the opening indent, we treat the entire block as invalid. + // + // I believe that code blocks of this form are actually valid Markdown + // in some cases, but the interplay between it and our docstring + // whitespace normalization leads to undesirable outcomes. For example, + // if the line here is unindented out beyond the initial indent of the + // docstring itself, then this causes the entire docstring to have + // its indent normalized. And, at the time of writing, a subsequent + // formatting run undoes this indentation, thus violating idempotency. + if !original.line.trim_whitespace().is_empty() + && indentation_length(original.line) < self.opening_fence_indent + { + queue.push_back(self.into_reset_action()); + queue.push_back(CodeExampleAddAction::Print { original }); + return None; + } + self.push(original); + queue.push_back(CodeExampleAddAction::Kept); + Some(self) + } + + /// Returns true when given line ends this fenced code block. + fn is_end(&self, original: InputDocstringLine<'src>) -> bool { + let (_, rest) = indent_with_suffix(original.line); + // We can bail early if we don't have at least three backticks or + // tildes. + if !rest.starts_with("```") && !rest.starts_with("~~~") { + return false; + } + // We do need to check that we have the right number of + // backticks/tildes... + let fence_len = rest + .chars() + .take_while(|&ch| ch == self.fence_kind.to_char()) + .count(); + // A closing fence only needs *at least* the number of ticks/tildes + // that are in the opening fence. + if fence_len < self.fence_len { + return false; + } + // And, also, there can only be trailing whitespace. Nothing else. + assert!( + self.fence_kind.to_char().is_ascii(), + "fence char should be ASCII", + ); + if !rest[fence_len..].chars().all(is_python_whitespace) { + return false; + } + true + } + + /// Pushes the given line as part of this code example. + fn push(&mut self, original: InputDocstringLine<'src>) { + // Unlike reStructuredText blocks, for Markdown fenced code blocks, the + // indentation that we want to strip from each line is known when the + // block is opened. So we can strip it as we collect lines. + let code = indentation_trim(self.opening_fence_indent, original.line); + self.lines.push(CodeExampleLine { original, code }); + } + + /// Consume this block and turn it into a reset action. + /// + /// This occurs when we started collecting a code example from something + /// that looked like a block, but later determined that it wasn't a valid + /// block. + fn into_format_action(self) -> CodeExampleAddAction<'src> { + // Note that unlike in reStructuredText blocks, if a Markdown fenced + // code block is unclosed, then *all* remaining lines should be treated + // as part of the block[1]: + // + // > If the end of the containing block (or document) is reached and no + // > closing code fence has been found, the code block contains all of the + // > lines after the opening code fence until the end of the containing + // > block (or document). + // + // This means that we don't need to try and trim trailing empty lines. + // Those will get fed into the code formatter and ultimately stripped, + // which is what you'd expect if those lines are treated as part of the + // block. + // + // [1]: https://spec.commonmark.org/0.30/#fenced-code-blocks + CodeExampleAddAction::Format { + kind: CodeExampleKind::Markdown(self), + } + } + + /// Consume this block and turn it into a reset action. + /// + /// This occurs when we started collecting a code example from something + /// that looked like a code fence, but later determined that it wasn't a + /// valid. + fn into_reset_action(self) -> CodeExampleAddAction<'src> { + CodeExampleAddAction::Reset { code: self.lines } + } +} + +/// The kind of fence used in a Markdown code block. +/// +/// This indicates that the fence is either surrounded by fences made from +/// backticks, or fences made from tildes. +#[derive(Clone, Copy, Debug)] +enum MarkdownFenceKind { + Backtick, + Tilde, +} + +impl MarkdownFenceKind { + /// Convert the fence kind to the actual character used to build the fence. + fn to_char(self) -> char { + match self { + MarkdownFenceKind::Backtick => '`', + MarkdownFenceKind::Tilde => '~', + } + } +} + +/// A single line in a code example found in a docstring. +/// +/// A code example line exists prior to formatting, and is thus in full +/// correspondence with the original lines from the docstring. Indeed, a +/// code example line includes both the original line *and* the actual code +/// extracted from the line. For example, if a line in a docstring is `>>> +/// foo(x)`, then the original line is `>>> foo(x)` and the code portion is +/// `foo(x)`. +/// +/// The original line is kept for things like offset information, but also +/// because it may still be needed if it turns out that the code snippet is +/// not valid or otherwise could not be formatted. In which case, the original +/// lines are printed as-is. +#[derive(Debug)] +struct CodeExampleLine<'src> { + /// The normalized (but original) line from the doc string. This might, for + /// example, contain a `>>> ` or `... ` prefix if this code example is a + /// doctest. + original: InputDocstringLine<'src>, + + /// The code extracted from the line. + code: &'src str, +} + +/// An action that a caller should perform after attempting to add a line from +/// a docstring to a code example. +/// +/// Callers are expected to add every line from a docstring to a code example, +/// and the state of the code example (and the line itself) will determine +/// how the caller should react. +#[derive(Debug)] +enum CodeExampleAddAction<'src> { + /// The line added was ignored by `CodeExample` and the caller should print + /// it to the formatter as-is. + /// + /// This is the common case. That is, most lines in most docstrings are not + /// part of a code example. + Print { original: InputDocstringLine<'src> }, + /// The line added was kept by `CodeExample` as part of a new or existing + /// code example. + /// + /// When this occurs, callers should not try to format the line and instead + /// move on to the next line. + Kept, + /// The line added indicated that the code example is finished and should + /// be formatted and printed. The line added is not treated as part of + /// the code example. + Format { + /// The kind of code example that was found. + kind: CodeExampleKind<'src>, + }, + /// This occurs when adding a line to an existing code example + /// results in that code example becoming invalid. In this case, + /// we don't want to treat it as a code example, but instead write + /// back the lines to the docstring unchanged. + #[allow(dead_code)] // FIXME: remove when reStructuredText support is added + Reset { + /// The lines of code that we collected but should be printed back to + /// the docstring as-is and not formatted. + code: Vec>, + }, +} + +/// Formats the given source code using the given options. +/// +/// The given quote style should correspond to the style used by the docstring +/// containing the code snippet being formatted. The formatter will use this +/// information to invert the quote style of any such strings contained within +/// the code snippet in order to avoid writing invalid Python code. +/// +/// This is similar to the top-level formatting entrypoint, except this +/// explicitly sets the context to indicate that formatting is taking place +/// inside of a docstring. +fn docstring_format_source( + options: crate::PyFormatOptions, + docstring_quote_style: QuoteChar, + source: &str, +) -> Result { + use ruff_python_parser::AsMode; + + let source_type = options.source_type(); + let (tokens, comment_ranges) = ruff_python_index::tokens_and_ranges(source, source_type)?; + let module = + ruff_python_parser::parse_ok_tokens(tokens, source, source_type.as_mode(), "")?; + let source_code = ruff_formatter::SourceCode::new(source); + let comments = crate::Comments::from_ast(&module, source_code, &comment_ranges); + let locator = Locator::new(source); + + let ctx = PyFormatContext::new(options, locator.contents(), comments) + .in_docstring(docstring_quote_style); + let formatted = crate::format!(ctx, [module.format()])?; + formatted + .context() + .comments() + .assert_all_formatted(source_code); + Ok(formatted.print()?) +} + +/// If the last line of the docstring is `content" """` or `content\ """`, we need a chaperone space +/// that avoids `content""""` and `content\"""`. This does only applies to un-escaped backslashes, +/// so `content\\ """` doesn't need a space while `content\\\ """` does. +fn needs_chaperone_space(normalized: &NormalizedString, trim_end: &str) -> bool { + trim_end.ends_with(normalized.quotes.quote_char.as_char()) + || trim_end.chars().rev().take_while(|c| *c == '\\').count() % 2 == 1 +} + +/// For docstring indentation, black counts spaces as 1 and tabs by increasing the indentation up +/// to the next multiple of 8. This is effectively a port of +/// [`str.expandtabs`](https://docs.python.org/3/library/stdtypes.html#str.expandtabs), +/// which black [calls with the default tab width of 8](https://github.com/psf/black/blob/c36e468794f9256d5e922c399240d49782ba04f1/src/black/strings.py#L61). +fn indentation_length(line: &str) -> TextSize { + let mut indentation = 0u32; + for char in line.chars() { + if char == '\t' { + // Pad to the next multiple of tab_width + indentation += 8 - (indentation.rem_euclid(8)); + } else if char.is_whitespace() { + indentation += u32::from(char.text_len()); + } else { + break; + } + } + TextSize::new(indentation) +} + +/// Trims at most `indent_len` indentation from the beginning of `line`. +/// +/// This treats indentation in precisely the same way as `indentation_length`. +/// As such, it is expected that `indent_len` is computed from +/// `indentation_length`. This is useful when one needs to trim some minimum +/// level of indentation from a code snippet collected from a docstring before +/// attempting to reformat it. +fn indentation_trim(indent_len: TextSize, line: &str) -> &str { + let mut seen_indent_len = 0u32; + let mut trimmed = line; + for char in line.chars() { + if seen_indent_len >= indent_len.to_u32() { + return trimmed; + } + if char == '\t' { + // Pad to the next multiple of tab_width + seen_indent_len += 8 - (seen_indent_len.rem_euclid(8)); + trimmed = &trimmed[1..]; + } else if char.is_whitespace() { + seen_indent_len += u32::from(char.text_len()); + trimmed = &trimmed[char.len_utf8()..]; + } else { + break; + } + } + trimmed +} + +/// Returns the indentation of the given line and everything following it. +fn indent_with_suffix(line: &str) -> (&str, &str) { + let suffix = line.trim_whitespace_start(); + let indent_len = line + .len() + .checked_sub(suffix.len()) + .expect("suffix <= line"); + let indent = &line[..indent_len]; + (indent, suffix) +} + +/// Returns true if this line looks like a reStructuredText option in a +/// field list. +/// +/// That is, a line that looks like `:name: optional-value`. +fn is_rst_option(line: &str) -> bool { + let line = line.trim_start(); + if !line.starts_with(':') { + return false; + } + line.chars() + .take_while(|&ch| !is_python_whitespace(ch)) + .any(|ch| ch == ':') +} + +#[cfg(test)] +mod tests { + use ruff_text_size::TextSize; + + use super::indentation_length; + + #[test] + fn test_indentation_like_black() { + assert_eq!(indentation_length("\t \t \t"), TextSize::new(24)); + assert_eq!(indentation_length("\t \t"), TextSize::new(24)); + assert_eq!(indentation_length("\t\t\t"), TextSize::new(24)); + assert_eq!(indentation_length(" "), TextSize::new(4)); + } +} diff --git a/crates/ruff_python_formatter/src/string/mod.rs b/crates/ruff_python_formatter/src/string/mod.rs new file mode 100644 index 0000000000000..57c11cd622900 --- /dev/null +++ b/crates/ruff_python_formatter/src/string/mod.rs @@ -0,0 +1,804 @@ +use std::borrow::Cow; + +use bitflags::bitflags; + +use ruff_formatter::{format_args, write}; +use ruff_python_ast::AnyNodeRef; +use ruff_python_ast::{ + self as ast, Expr, ExprBytesLiteral, ExprFString, ExprStringLiteral, ExpressionRef, +}; +use ruff_source_file::Locator; +use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; + +use crate::comments::{leading_comments, trailing_comments}; +use crate::expression::expr_f_string::f_string_quoting; +use crate::expression::parentheses::in_parentheses_only_soft_line_break_or_space; +use crate::other::f_string::FormatFString; +use crate::other::string_literal::{FormatStringLiteral, StringLiteralKind}; +use crate::prelude::*; +use crate::QuoteStyle; + +pub(crate) mod docstring; + +#[derive(Copy, Clone, Debug, Default)] +pub(crate) enum Quoting { + #[default] + CanChange, + Preserve, +} + +/// Represents any kind of string expression. This could be either a string, +/// bytes or f-string. +#[derive(Clone, Debug)] +pub(crate) enum AnyString<'a> { + String(&'a ExprStringLiteral), + Bytes(&'a ExprBytesLiteral), + FString(&'a ExprFString), +} + +impl<'a> AnyString<'a> { + /// Creates a new [`AnyString`] from the given [`Expr`]. + /// + /// Returns `None` if the expression is not either a string, bytes or f-string. + pub(crate) fn from_expression(expression: &'a Expr) -> Option> { + match expression { + Expr::StringLiteral(string) => Some(AnyString::String(string)), + Expr::BytesLiteral(bytes) => Some(AnyString::Bytes(bytes)), + Expr::FString(fstring) => Some(AnyString::FString(fstring)), + _ => None, + } + } + + /// Returns `true` if the string is implicitly concatenated. + pub(crate) fn is_implicit_concatenated(&self) -> bool { + match self { + Self::String(ExprStringLiteral { value, .. }) => value.is_implicit_concatenated(), + Self::Bytes(ExprBytesLiteral { value, .. }) => value.is_implicit_concatenated(), + Self::FString(ExprFString { value, .. }) => value.is_implicit_concatenated(), + } + } + + /// Returns the quoting to be used for this string. + fn quoting(&self, locator: &Locator<'_>) -> Quoting { + match self { + Self::String(_) | Self::Bytes(_) => Quoting::CanChange, + Self::FString(f_string) => f_string_quoting(f_string, locator), + } + } + + /// Returns a vector of all the [`AnyStringPart`] of this string. + fn parts(&self, quoting: Quoting) -> Vec> { + match self { + Self::String(ExprStringLiteral { value, .. }) => value + .iter() + .map(|part| AnyStringPart::String { + part, + layout: StringLiteralKind::String, + }) + .collect(), + Self::Bytes(ExprBytesLiteral { value, .. }) => { + value.iter().map(AnyStringPart::Bytes).collect() + } + Self::FString(ExprFString { value, .. }) => value + .iter() + .map(|f_string_part| match f_string_part { + ast::FStringPart::Literal(string_literal) => AnyStringPart::String { + part: string_literal, + layout: StringLiteralKind::InImplicitlyConcatenatedFString(quoting), + }, + ast::FStringPart::FString(f_string) => AnyStringPart::FString { + part: f_string, + quoting, + }, + }) + .collect(), + } + } +} + +impl Ranged for AnyString<'_> { + fn range(&self) -> TextRange { + match self { + Self::String(expr) => expr.range(), + Self::Bytes(expr) => expr.range(), + Self::FString(expr) => expr.range(), + } + } +} + +impl<'a> From<&AnyString<'a>> for AnyNodeRef<'a> { + fn from(value: &AnyString<'a>) -> Self { + match value { + AnyString::String(expr) => AnyNodeRef::ExprStringLiteral(expr), + AnyString::Bytes(expr) => AnyNodeRef::ExprBytesLiteral(expr), + AnyString::FString(expr) => AnyNodeRef::ExprFString(expr), + } + } +} + +impl<'a> From<&AnyString<'a>> for ExpressionRef<'a> { + fn from(value: &AnyString<'a>) -> Self { + match value { + AnyString::String(expr) => ExpressionRef::StringLiteral(expr), + AnyString::Bytes(expr) => ExpressionRef::BytesLiteral(expr), + AnyString::FString(expr) => ExpressionRef::FString(expr), + } + } +} + +/// Represents any kind of string which is part of an implicitly concatenated +/// string. This could be either a string, bytes or f-string. +/// +/// This is constructed from the [`AnyString::parts`] method on [`AnyString`]. +#[derive(Clone, Debug)] +enum AnyStringPart<'a> { + String { + part: &'a ast::StringLiteral, + layout: StringLiteralKind, + }, + Bytes(&'a ast::BytesLiteral), + FString { + part: &'a ast::FString, + quoting: Quoting, + }, +} + +impl<'a> From<&AnyStringPart<'a>> for AnyNodeRef<'a> { + fn from(value: &AnyStringPart<'a>) -> Self { + match value { + AnyStringPart::String { part, .. } => AnyNodeRef::StringLiteral(part), + AnyStringPart::Bytes(part) => AnyNodeRef::BytesLiteral(part), + AnyStringPart::FString { part, .. } => AnyNodeRef::FString(part), + } + } +} + +impl Ranged for AnyStringPart<'_> { + fn range(&self) -> TextRange { + match self { + Self::String { part, .. } => part.range(), + Self::Bytes(part) => part.range(), + Self::FString { part, .. } => part.range(), + } + } +} + +impl Format> for AnyStringPart<'_> { + fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { + match self { + AnyStringPart::String { part, layout } => { + FormatStringLiteral::new(part, *layout).fmt(f) + } + AnyStringPart::Bytes(bytes_literal) => bytes_literal.format().fmt(f), + AnyStringPart::FString { part, quoting } => FormatFString::new(part, *quoting).fmt(f), + } + } +} + +/// Formats any implicitly concatenated string. This could be any valid combination +/// of string, bytes or f-string literals. +pub(crate) struct FormatStringContinuation<'a> { + string: &'a AnyString<'a>, +} + +impl<'a> FormatStringContinuation<'a> { + pub(crate) fn new(string: &'a AnyString<'a>) -> Self { + Self { string } + } +} + +impl Format> for FormatStringContinuation<'_> { + fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { + let comments = f.context().comments().clone(); + let quoting = self.string.quoting(&f.context().locator()); + + let mut joiner = f.join_with(in_parentheses_only_soft_line_break_or_space()); + + for part in self.string.parts(quoting) { + joiner.entry(&format_args![ + line_suffix_boundary(), + leading_comments(comments.leading(&part)), + part, + trailing_comments(comments.trailing(&part)) + ]); + } + + joiner.finish() + } +} + +#[derive(Debug)] +pub(crate) struct StringPart { + /// The prefix. + prefix: StringPrefix, + + /// The actual quotes of the string in the source + quotes: StringQuotes, + + /// The range of the string's content (full range minus quotes and prefix) + content_range: TextRange, +} + +impl StringPart { + pub(crate) fn from_source(range: TextRange, locator: &Locator) -> Self { + let string_content = locator.slice(range); + + let prefix = StringPrefix::parse(string_content); + let after_prefix = &string_content[usize::from(prefix.text_len())..]; + + let quotes = + StringQuotes::parse(after_prefix).expect("Didn't find string quotes after prefix"); + let relative_raw_content_range = TextRange::new( + prefix.text_len() + quotes.text_len(), + string_content.text_len() - quotes.text_len(), + ); + let raw_content_range = relative_raw_content_range + range.start(); + + Self { + prefix, + content_range: raw_content_range, + quotes, + } + } + + /// Computes the strings preferred quotes and normalizes its content. + /// + /// The parent docstring quote style should be set when formatting a code + /// snippet within the docstring. The quote style should correspond to the + /// style of quotes used by said docstring. Normalization will ensure the + /// quoting styles don't conflict. + pub(crate) fn normalize<'a>( + self, + quoting: Quoting, + locator: &'a Locator, + configured_style: QuoteStyle, + parent_docstring_quote_char: Option, + ) -> NormalizedString<'a> { + // Per PEP 8, always prefer double quotes for triple-quoted strings. + let preferred_style = if self.quotes.triple { + // ... unless we're formatting a code snippet inside a docstring, + // then we specifically want to invert our quote style to avoid + // writing out invalid Python. + // + // It's worth pointing out that we can actually wind up being + // somewhat out of sync with PEP8 in this case. Consider this + // example: + // + // def foo(): + // ''' + // Something. + // + // >>> """tricksy""" + // ''' + // pass + // + // Ideally, this would be reformatted as: + // + // def foo(): + // """ + // Something. + // + // >>> '''tricksy''' + // """ + // pass + // + // But the logic here results in the original quoting being + // preserved. This is because the quoting style of the outer + // docstring is determined, in part, by looking at its contents. In + // this case, it notices that it contains a `"""` and thus infers + // that using `'''` would overall read better because it avoids + // the need to escape the interior `"""`. Except... in this case, + // the `"""` is actually part of a code snippet that could get + // reformatted to using a different quoting style itself. + // + // Fixing this would, I believe, require some fairly seismic + // changes to how formatting strings works. Namely, we would need + // to look for code snippets before normalizing the docstring, and + // then figure out the quoting style more holistically by looking + // at the various kinds of quotes used in the code snippets and + // what reformatting them might look like. + // + // Overall this is a bit of a corner case and just inverting the + // style from what the parent ultimately decided upon works, even + // if it doesn't have perfect alignment with PEP8. + if let Some(quote) = parent_docstring_quote_char { + QuoteStyle::from(quote.invert()) + } else { + QuoteStyle::Double + } + } else { + configured_style + }; + + let raw_content = locator.slice(self.content_range); + + let quotes = match quoting { + Quoting::Preserve => self.quotes, + Quoting::CanChange => { + if let Some(preferred_quote) = QuoteChar::from_style(preferred_style) { + if self.prefix.is_raw_string() { + choose_quotes_raw(raw_content, self.quotes, preferred_quote) + } else { + choose_quotes(raw_content, self.quotes, preferred_quote) + } + } else { + self.quotes + } + } + }; + + let normalized = normalize_string(locator.slice(self.content_range), quotes, self.prefix); + + NormalizedString { + prefix: self.prefix, + content_range: self.content_range, + text: normalized, + quotes, + } + } +} + +#[derive(Debug)] +pub(crate) struct NormalizedString<'a> { + prefix: StringPrefix, + + /// The quotes of the normalized string (preferred quotes) + quotes: StringQuotes, + + /// The range of the string's content in the source (minus prefix and quotes). + content_range: TextRange, + + /// The normalized text + text: Cow<'a, str>, +} + +impl Ranged for NormalizedString<'_> { + fn range(&self) -> TextRange { + self.content_range + } +} + +impl Format> for NormalizedString<'_> { + fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { + write!(f, [self.prefix, self.quotes])?; + match &self.text { + Cow::Borrowed(_) => { + source_text_slice(self.range()).fmt(f)?; + } + Cow::Owned(normalized) => { + text(normalized, Some(self.start())).fmt(f)?; + } + } + self.quotes.fmt(f) + } +} + +bitflags! { + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + pub(crate) struct StringPrefix: u8 { + const UNICODE = 0b0000_0001; + /// `r"test"` + const RAW = 0b0000_0010; + /// `R"test" + const RAW_UPPER = 0b0000_0100; + const BYTE = 0b0000_1000; + const F_STRING = 0b0001_0000; + } +} + +impl StringPrefix { + pub(crate) fn parse(input: &str) -> StringPrefix { + let chars = input.chars(); + let mut prefix = StringPrefix::empty(); + + for c in chars { + let flag = match c { + 'u' | 'U' => StringPrefix::UNICODE, + 'f' | 'F' => StringPrefix::F_STRING, + 'b' | 'B' => StringPrefix::BYTE, + 'r' => StringPrefix::RAW, + 'R' => StringPrefix::RAW_UPPER, + '\'' | '"' => break, + c => { + unreachable!( + "Unexpected character '{c}' terminating the prefix of a string literal" + ); + } + }; + + prefix |= flag; + } + + prefix + } + + pub(crate) const fn text_len(self) -> TextSize { + TextSize::new(self.bits().count_ones()) + } + + pub(super) const fn is_raw_string(self) -> bool { + self.contains(StringPrefix::RAW) || self.contains(StringPrefix::RAW_UPPER) + } + + pub(super) const fn is_fstring(self) -> bool { + self.contains(StringPrefix::F_STRING) + } +} + +impl Format> for StringPrefix { + fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { + // Retain the casing for the raw prefix: + // https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#r-strings-and-r-strings + if self.contains(StringPrefix::RAW) { + token("r").fmt(f)?; + } else if self.contains(StringPrefix::RAW_UPPER) { + token("R").fmt(f)?; + } + + if self.contains(StringPrefix::BYTE) { + token("b").fmt(f)?; + } + + if self.contains(StringPrefix::F_STRING) { + token("f").fmt(f)?; + } + + // Remove the unicode prefix `u` if any because it is meaningless in Python 3+. + + Ok(()) + } +} + +/// Choose the appropriate quote style for a raw string. +/// +/// The preferred quote style is chosen unless the string contains unescaped quotes of the +/// preferred style. For example, `r"foo"` is chosen over `r'foo'` if the preferred quote +/// style is double quotes. +fn choose_quotes_raw( + input: &str, + quotes: StringQuotes, + preferred_quote: QuoteChar, +) -> StringQuotes { + let preferred_quote_char = preferred_quote.as_char(); + let mut chars = input.chars().peekable(); + let contains_unescaped_configured_quotes = loop { + match chars.next() { + Some('\\') => { + // Ignore escaped characters + chars.next(); + } + // `"` or `'` + Some(c) if c == preferred_quote_char => { + if !quotes.triple { + break true; + } + + match chars.peek() { + // We can't turn `r'''\""'''` into `r"""\"""""`, this would confuse the parser + // about where the closing triple quotes start + None => break true, + Some(next) if *next == preferred_quote_char => { + // `""` or `''` + chars.next(); + + // We can't turn `r'''""'''` into `r""""""""`, nor can we have + // `"""` or `'''` respectively inside the string + if chars.peek().is_none() || chars.peek() == Some(&preferred_quote_char) { + break true; + } + } + _ => {} + } + } + Some(_) => continue, + None => break false, + } + }; + + StringQuotes { + triple: quotes.triple, + quote_char: if contains_unescaped_configured_quotes { + quotes.quote_char + } else { + preferred_quote + }, + } +} + +/// Choose the appropriate quote style for a string. +/// +/// For single quoted strings, the preferred quote style is used, unless the alternative quote style +/// would require fewer escapes. +/// +/// For triple quoted strings, the preferred quote style is always used, unless the string contains +/// a triplet of the quote character (e.g., if double quotes are preferred, double quotes will be +/// used unless the string contains `"""`). +fn choose_quotes(input: &str, quotes: StringQuotes, preferred_quote: QuoteChar) -> StringQuotes { + let quote = if quotes.triple { + // True if the string contains a triple quote sequence of the configured quote style. + let mut uses_triple_quotes = false; + let mut chars = input.chars().peekable(); + + while let Some(c) = chars.next() { + let preferred_quote_char = preferred_quote.as_char(); + match c { + '\\' => { + if matches!(chars.peek(), Some('"' | '\\')) { + chars.next(); + } + } + // `"` or `'` + c if c == preferred_quote_char => { + match chars.peek().copied() { + Some(c) if c == preferred_quote_char => { + // `""` or `''` + chars.next(); + + match chars.peek().copied() { + Some(c) if c == preferred_quote_char => { + // `"""` or `'''` + chars.next(); + uses_triple_quotes = true; + break; + } + Some(_) => {} + None => { + // Handle `''' ""'''`. At this point we have consumed both + // double quotes, so on the next iteration the iterator is empty + // and we'd miss the string ending with a preferred quote + uses_triple_quotes = true; + break; + } + } + } + Some(_) => { + // A single quote char, this is ok + } + None => { + // Trailing quote at the end of the comment + uses_triple_quotes = true; + break; + } + } + } + _ => continue, + } + } + + if uses_triple_quotes { + // String contains a triple quote sequence of the configured quote style. + // Keep the existing quote style. + quotes.quote_char + } else { + preferred_quote + } + } else { + let mut single_quotes = 0u32; + let mut double_quotes = 0u32; + + for c in input.chars() { + match c { + '\'' => { + single_quotes += 1; + } + + '"' => { + double_quotes += 1; + } + + _ => continue, + } + } + + match preferred_quote { + QuoteChar::Single => { + if single_quotes > double_quotes { + QuoteChar::Double + } else { + QuoteChar::Single + } + } + QuoteChar::Double => { + if double_quotes > single_quotes { + QuoteChar::Single + } else { + QuoteChar::Double + } + } + } + }; + + StringQuotes { + triple: quotes.triple, + quote_char: quote, + } +} + +#[derive(Copy, Clone, Debug)] +pub(crate) struct StringQuotes { + triple: bool, + quote_char: QuoteChar, +} + +impl StringQuotes { + pub(crate) fn parse(input: &str) -> Option { + let mut chars = input.chars(); + + let quote_char = chars.next()?; + let quote = QuoteChar::try_from(quote_char).ok()?; + + let triple = chars.next() == Some(quote_char) && chars.next() == Some(quote_char); + + Some(Self { + triple, + quote_char: quote, + }) + } + + pub(crate) const fn is_triple(self) -> bool { + self.triple + } + + const fn text_len(self) -> TextSize { + if self.triple { + TextSize::new(3) + } else { + TextSize::new(1) + } + } +} + +impl Format> for StringQuotes { + fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { + let quotes = match (self.quote_char, self.triple) { + (QuoteChar::Single, false) => "'", + (QuoteChar::Single, true) => "'''", + (QuoteChar::Double, false) => "\"", + (QuoteChar::Double, true) => "\"\"\"", + }; + + token(quotes).fmt(f) + } +} + +/// The quotation character used to quote a string, byte, or fstring literal. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum QuoteChar { + /// A single quote: `'` + Single, + + /// A double quote: '"' + Double, +} + +impl QuoteChar { + pub const fn as_char(self) -> char { + match self { + QuoteChar::Single => '\'', + QuoteChar::Double => '"', + } + } + + #[must_use] + pub const fn invert(self) -> QuoteChar { + match self { + QuoteChar::Single => QuoteChar::Double, + QuoteChar::Double => QuoteChar::Single, + } + } + + #[must_use] + pub const fn from_style(style: QuoteStyle) -> Option { + match style { + QuoteStyle::Single => Some(QuoteChar::Single), + QuoteStyle::Double => Some(QuoteChar::Double), + QuoteStyle::Preserve => None, + } + } +} + +impl From for QuoteStyle { + fn from(value: QuoteChar) -> Self { + match value { + QuoteChar::Single => QuoteStyle::Single, + QuoteChar::Double => QuoteStyle::Double, + } + } +} + +impl TryFrom for QuoteChar { + type Error = (); + + fn try_from(value: char) -> Result { + match value { + '\'' => Ok(QuoteChar::Single), + '"' => Ok(QuoteChar::Double), + _ => Err(()), + } + } +} + +/// Adds the necessary quote escapes and removes unnecessary escape sequences when quoting `input` +/// with the provided [`StringQuotes`] style. +/// +/// Returns the normalized string and whether it contains new lines. +fn normalize_string(input: &str, quotes: StringQuotes, prefix: StringPrefix) -> Cow { + // The normalized string if `input` is not yet normalized. + // `output` must remain empty if `input` is already normalized. + let mut output = String::new(); + // Tracks the last index of `input` that has been written to `output`. + // If `last_index` is `0` at the end, then the input is already normalized and can be returned as is. + let mut last_index = 0; + + let quote = quotes.quote_char; + let preferred_quote = quote.as_char(); + let opposite_quote = quote.invert().as_char(); + + let mut chars = input.char_indices().peekable(); + + let is_raw = prefix.is_raw_string(); + let is_fstring = prefix.is_fstring(); + let mut formatted_value_nesting = 0u32; + + while let Some((index, c)) = chars.next() { + if is_fstring && matches!(c, '{' | '}') { + if chars.peek().copied().is_some_and(|(_, next)| next == c) { + // Skip over the second character of the double braces + chars.next(); + } else if c == '{' { + formatted_value_nesting += 1; + } else { + // Safe to assume that `c == '}'` here because of the matched pattern above + formatted_value_nesting = formatted_value_nesting.saturating_sub(1); + } + continue; + } + if c == '\r' { + output.push_str(&input[last_index..index]); + + // Skip over the '\r' character, keep the `\n` + if chars.peek().copied().is_some_and(|(_, next)| next == '\n') { + chars.next(); + } + // Replace the `\r` with a `\n` + else { + output.push('\n'); + } + + last_index = index + '\r'.len_utf8(); + } else if !quotes.triple && !is_raw { + if c == '\\' { + if let Some((_, next)) = chars.peek().copied() { + #[allow(clippy::if_same_then_else)] + if next == opposite_quote && formatted_value_nesting == 0 { + // Remove the escape by ending before the backslash and starting again with the quote + chars.next(); + output.push_str(&input[last_index..index]); + last_index = index + '\\'.len_utf8(); + } else if next == preferred_quote { + // Quote is already escaped, skip over it. + chars.next(); + } else if next == '\\' { + // Skip over escaped backslashes + chars.next(); + } + } + } else if c == preferred_quote && formatted_value_nesting == 0 { + // Escape the quote + output.push_str(&input[last_index..index]); + output.push('\\'); + output.push(c); + last_index = index + preferred_quote.len_utf8(); + } + } + } + + let normalized = if last_index == 0 { + Cow::Borrowed(input) + } else { + output.push_str(&input[last_index..]); + Cow::Owned(output) + }; + + normalized +} diff --git a/crates/ruff_python_formatter/tests/fixtures.rs b/crates/ruff_python_formatter/tests/fixtures.rs index c3fd2b20707e8..3845385d7335f 100644 --- a/crates/ruff_python_formatter/tests/fixtures.rs +++ b/crates/ruff_python_formatter/tests/fixtures.rs @@ -20,9 +20,10 @@ fn black_compatibility() { let options_path = input_path.with_extension("options.json"); - let options: PyFormatOptions = if let Ok(options_file) = fs::File::open(options_path) { + let options: PyFormatOptions = if let Ok(options_file) = fs::File::open(&options_path) { let reader = BufReader::new(options_file); - serde_json::from_reader(reader).expect("Options to be a valid Json file") + serde_json::from_reader(reader) + .unwrap_or_else(|_| panic!("Option file {options_path:?} to be a valid Json file")) } else { PyFormatOptions::from_extension(input_path) }; @@ -34,14 +35,18 @@ fn black_compatibility() { ) }); - let expected_path = input_path.with_extension("py.expect"); + let extension = input_path + .extension() + .expect("Test file to have py or pyi extension") + .to_string_lossy(); + let expected_path = input_path.with_extension(format!("{extension}.expect")); let expected_output = fs::read_to_string(&expected_path) .unwrap_or_else(|_| panic!("Expected Black output file '{expected_path:?}' to exist")); let formatted_code = printed.as_code(); ensure_unchanged_ast(&content, formatted_code, &options, input_path); - ensure_stability_when_formatting_twice(formatted_code, options, input_path); + ensure_stability_when_formatting_twice(formatted_code, &options, input_path); if formatted_code == expected_output { // Black and Ruff formatting matches. Delete any existing snapshot files because the Black output @@ -106,7 +111,11 @@ fn black_compatibility() { } }; - insta::glob!("../resources", "test/fixtures/black/**/*.py", test_file); + insta::glob!( + "../resources", + "test/fixtures/black/**/*.{py,pyi}", + test_file + ); } #[test] @@ -120,7 +129,7 @@ fn format() { let formatted_code = printed.as_code(); ensure_unchanged_ast(&content, formatted_code, &options, input_path); - ensure_stability_when_formatting_twice(formatted_code, options.clone(), input_path); + ensure_stability_when_formatting_twice(formatted_code, &options, input_path); let mut snapshot = format!("## Input\n{}", CodeFrame::new("python", &content)); @@ -138,7 +147,7 @@ fn format() { let formatted_code = printed.as_code(); ensure_unchanged_ast(&content, formatted_code, &options, input_path); - ensure_stability_when_formatting_twice(formatted_code, options.clone(), input_path); + ensure_stability_when_formatting_twice(formatted_code, &options, input_path); writeln!( snapshot, @@ -157,7 +166,7 @@ fn format() { let formatted_preview = printed_preview.as_code(); ensure_unchanged_ast(&content, formatted_preview, &options_preview, input_path); - ensure_stability_when_formatting_twice(formatted_preview, options_preview, input_path); + ensure_stability_when_formatting_twice(formatted_preview, &options_preview, input_path); if formatted_code == formatted_preview { writeln!( @@ -203,10 +212,10 @@ fn format() { /// Format another time and make sure that there are no changes anymore fn ensure_stability_when_formatting_twice( formatted_code: &str, - options: PyFormatOptions, + options: &PyFormatOptions, input_path: &Path, ) { - let reformatted = match format_module_source(formatted_code, options) { + let reformatted = match format_module_source(formatted_code, options.clone()) { Ok(reformatted) => reformatted, Err(err) => { panic!( @@ -223,7 +232,10 @@ fn ensure_stability_when_formatting_twice( .header("Formatted once", "Formatted twice") .to_string(); panic!( - r#"Reformatting the formatted code of {} a second time resulted in formatting changes. + r#"Reformatting the formatted code of {input_path} a second time resulted in formatting changes. + +Options: +{options} --- {diff}--- @@ -233,9 +245,10 @@ Formatted once: Formatted twice: --- -{}---"#, - input_path.display(), - reformatted.as_code(), +{reformatted}---"#, + input_path = input_path.display(), + options = &DisplayPyOptions(options), + reformatted = reformatted.as_code(), ); } } @@ -334,17 +347,23 @@ impl fmt::Display for DisplayPyOptions<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { writeln!( f, - r#"indent-style = {indent_style} -line-width = {line_width} -indent-width = {indent_width} -quote-style = {quote_style:?} -magic-trailing-comma = {magic_trailing_comma:?} -preview = {preview:?}"#, + r#"indent-style = {indent_style} +line-width = {line_width} +indent-width = {indent_width} +quote-style = {quote_style:?} +line-ending = {line_ending:?} +magic-trailing-comma = {magic_trailing_comma:?} +docstring-code = {docstring_code:?} +docstring-code-line-width = {docstring_code_line_width:?} +preview = {preview:?}"#, indent_style = self.0.indent_style(), indent_width = self.0.indent_width().value(), line_width = self.0.line_width().value(), quote_style = self.0.quote_style(), + line_ending = self.0.line_ending(), magic_trailing_comma = self.0.magic_trailing_comma(), + docstring_code = self.0.docstring_code(), + docstring_code_line_width = self.0.docstring_code_line_width(), preview = self.0.preview() ) } diff --git a/crates/ruff_python_formatter/tests/normalizer.rs b/crates/ruff_python_formatter/tests/normalizer.rs index 68c15349dd173..2bab8915cc054 100644 --- a/crates/ruff_python_formatter/tests/normalizer.rs +++ b/crates/ruff_python_formatter/tests/normalizer.rs @@ -1,4 +1,8 @@ -use itertools::Either::{Left, Right}; +use { + itertools::Either::{Left, Right}, + once_cell::sync::Lazy, + regex::Regex, +}; use ruff_python_ast::visitor::transformer; use ruff_python_ast::visitor::transformer::Transformer; @@ -12,6 +16,10 @@ use ruff_python_ast::{self as ast, Expr, Stmt}; /// between `class C: ...` and `class C(): ...`, which is part of our AST but not `CPython`'s. /// - Normalize strings. The formatter can re-indent docstrings, so we need to compare string /// contents ignoring whitespace. (Black does the same.) +/// - The formatter can also reformat code snippets when they're Python code, which can of +/// course change the string in arbitrary ways. Black itself does not reformat code snippets, +/// so we carve our own path here by stripping everything that looks like code snippets from +/// string literals. /// - Ignores nested tuples in deletions. (Black does the same.) pub(crate) struct Normalizer; @@ -51,20 +59,64 @@ impl Transformer for Normalizer { transformer::walk_stmt(self, stmt); } - fn visit_expr(&self, expr: &mut Expr) { - if let Expr::StringLiteral(string_literal) = expr { - // Normalize a string by (1) stripping any leading and trailing space from each - // line, and (2) removing any blank lines from the start and end of the string. - string_literal.value = string_literal - .value - .lines() - .map(str::trim) - .collect::>() - .join("\n") - .trim() - .to_owned(); - } + fn visit_string_literal(&self, string_literal: &mut ast::StringLiteral) { + static STRIP_DOC_TESTS: Lazy = Lazy::new(|| { + Regex::new( + r#"(?mx) + ( + # strip doctest PS1 prompt lines + ^\s*>>>\s.*(\n|$) + | + # strip doctest PS2 prompt lines + # Also handles the case of an empty ... line. + ^\s*\.\.\.((\n|$)|\s.*(\n|$)) + )+ + "#, + ) + .unwrap() + }); + static STRIP_RST_BLOCKS: Lazy = Lazy::new(|| { + // This is kind of unfortunate, but it's pretty tricky (likely + // impossible) to detect a reStructuredText block with a simple + // regex. So we just look for the start of a block and remove + // everything after it. Talk about a hammer. + Regex::new(r#"::(?s:.*)"#).unwrap() + }); + static STRIP_MARKDOWN_BLOCKS: Lazy = Lazy::new(|| { + // This covers more than valid Markdown blocks, but that's OK. + Regex::new(r#"(```|~~~)\p{any}*(```|~~~|$)"#).unwrap() + }); - transformer::walk_expr(self, expr); + // Start by (1) stripping everything that looks like a code + // snippet, since code snippets may be completely reformatted if + // they are Python code. + string_literal.value = STRIP_DOC_TESTS + .replace_all( + &string_literal.value, + "\n", + ) + .into_owned(); + string_literal.value = STRIP_RST_BLOCKS + .replace_all( + &string_literal.value, + "\n", + ) + .into_owned(); + string_literal.value = STRIP_MARKDOWN_BLOCKS + .replace_all( + &string_literal.value, + "\n", + ) + .into_owned(); + // Normalize a string by (2) stripping any leading and trailing space from each + // line, and (3) removing any blank lines from the start and end of the string. + string_literal.value = string_literal + .value + .lines() + .map(str::trim) + .collect::>() + .join("\n") + .trim() + .to_owned(); } } diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comment_after_escaped_newline.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comment_after_escaped_newline.py.snap similarity index 93% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comment_after_escaped_newline.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comment_after_escaped_newline.py.snap index 9656ed1e16fe5..d936affef1eb1 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comment_after_escaped_newline.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comment_after_escaped_newline.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comment_after_escaped_newline.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/comment_after_escaped_newline.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments2.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments2.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments2.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments2.py.snap index 9c0622bce3e52..d9273e29931e1 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments2.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments2.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments2.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments2.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments6.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments6.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments6.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments6.py.snap index 45ab60a21a43b..f1bc3b617373d 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments6.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments6.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments6.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments6.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments9.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments9.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments9.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments9.py.snap index 743906edda155..5e25b161c919a 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__comments9.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments9.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/comments9.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments9.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments_in_blocks.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments_in_blocks.py.snap new file mode 100644 index 0000000000000..7524d7c7a7717 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__comments_in_blocks.py.snap @@ -0,0 +1,382 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/comments_in_blocks.py +--- +## Input + +```python +# Test cases from: +# - https://github.com/psf/black/issues/1798 +# - https://github.com/psf/black/issues/1499 +# - https://github.com/psf/black/issues/1211 +# - https://github.com/psf/black/issues/563 + +( + lambda + # a comment + : None +) + +( + lambda: + # b comment + None +) + +( + lambda + # a comment + : + # b comment + None +) + +[ + x + # Let's do this + for + # OK? + x + # Some comment + # And another + in + # One more + y +] + +return [ + (offers[offer_index], 1.0) + for offer_index, _ + # avoid returning any offers that don't match the grammar so + # that the return values here are consistent with what would be + # returned in AcceptValidHeader + in self._parse_and_normalize_offers(offers) +] + +from foo import ( + bar, + # qux +) + + +def convert(collection): + # replace all variables by integers + replacement_dict = { + variable: f"{index}" + for index, variable + # 0 is reserved as line terminator + in enumerate(collection.variables(), start=1) + } + + +{ + i: i + for i + # a comment + in range(5) +} + + +def get_subtree_proof_nodes( + chunk_index_groups: Sequence[Tuple[int, ...], ...], +) -> Tuple[int, ...]: + subtree_node_paths = ( + # We take a candidate element from each group and shift it to + # remove the bits that are not common to other group members, then + # we convert it to a tree path that all elements from this group + # have in common. + chunk_index + for chunk_index, bits_to_truncate + # Each group will contain an even "power-of-two" number of# elements. + # This tells us how many tailing bits each element has# which need to + # be truncated to get the group's common prefix. + in ((group[0], (len(group) - 1).bit_length()) for group in chunk_index_groups) + ) + return subtree_node_paths + + +if ( + # comment1 + a + # comment2 + or ( + # comment3 + ( + # comment4 + b + ) + # comment5 + and + # comment6 + c + or ( + # comment7 + d + ) + ) +): + print("Foo") +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -5,9 +5,9 @@ + # - https://github.com/psf/black/issues/563 + + ( +- lambda ++ lambda: + # a comment +- : None ++ None + ) + + ( +@@ -17,9 +17,8 @@ + ) + + ( +- lambda ++ lambda: + # a comment +- : + # b comment + None + ) +``` + +## Ruff Output + +```python +# Test cases from: +# - https://github.com/psf/black/issues/1798 +# - https://github.com/psf/black/issues/1499 +# - https://github.com/psf/black/issues/1211 +# - https://github.com/psf/black/issues/563 + +( + lambda: + # a comment + None +) + +( + lambda: + # b comment + None +) + +( + lambda: + # a comment + # b comment + None +) + +[ + x + # Let's do this + for + # OK? + x + # Some comment + # And another + in + # One more + y +] + +return [ + (offers[offer_index], 1.0) + for offer_index, _ + # avoid returning any offers that don't match the grammar so + # that the return values here are consistent with what would be + # returned in AcceptValidHeader + in self._parse_and_normalize_offers(offers) +] + +from foo import ( + bar, + # qux +) + + +def convert(collection): + # replace all variables by integers + replacement_dict = { + variable: f"{index}" + for index, variable + # 0 is reserved as line terminator + in enumerate(collection.variables(), start=1) + } + + +{ + i: i + for i + # a comment + in range(5) +} + + +def get_subtree_proof_nodes( + chunk_index_groups: Sequence[Tuple[int, ...], ...], +) -> Tuple[int, ...]: + subtree_node_paths = ( + # We take a candidate element from each group and shift it to + # remove the bits that are not common to other group members, then + # we convert it to a tree path that all elements from this group + # have in common. + chunk_index + for chunk_index, bits_to_truncate + # Each group will contain an even "power-of-two" number of# elements. + # This tells us how many tailing bits each element has# which need to + # be truncated to get the group's common prefix. + in ((group[0], (len(group) - 1).bit_length()) for group in chunk_index_groups) + ) + return subtree_node_paths + + +if ( + # comment1 + a + # comment2 + or ( + # comment3 + ( + # comment4 + b + ) + # comment5 + and + # comment6 + c + or ( + # comment7 + d + ) + ) +): + print("Foo") +``` + +## Black Output + +```python +# Test cases from: +# - https://github.com/psf/black/issues/1798 +# - https://github.com/psf/black/issues/1499 +# - https://github.com/psf/black/issues/1211 +# - https://github.com/psf/black/issues/563 + +( + lambda + # a comment + : None +) + +( + lambda: + # b comment + None +) + +( + lambda + # a comment + : + # b comment + None +) + +[ + x + # Let's do this + for + # OK? + x + # Some comment + # And another + in + # One more + y +] + +return [ + (offers[offer_index], 1.0) + for offer_index, _ + # avoid returning any offers that don't match the grammar so + # that the return values here are consistent with what would be + # returned in AcceptValidHeader + in self._parse_and_normalize_offers(offers) +] + +from foo import ( + bar, + # qux +) + + +def convert(collection): + # replace all variables by integers + replacement_dict = { + variable: f"{index}" + for index, variable + # 0 is reserved as line terminator + in enumerate(collection.variables(), start=1) + } + + +{ + i: i + for i + # a comment + in range(5) +} + + +def get_subtree_proof_nodes( + chunk_index_groups: Sequence[Tuple[int, ...], ...], +) -> Tuple[int, ...]: + subtree_node_paths = ( + # We take a candidate element from each group and shift it to + # remove the bits that are not common to other group members, then + # we convert it to a tree path that all elements from this group + # have in common. + chunk_index + for chunk_index, bits_to_truncate + # Each group will contain an even "power-of-two" number of# elements. + # This tells us how many tailing bits each element has# which need to + # be truncated to get the group's common prefix. + in ((group[0], (len(group) - 1).bit_length()) for group in chunk_index_groups) + ) + return subtree_node_paths + + +if ( + # comment1 + a + # comment2 + or ( + # comment3 + ( + # comment4 + b + ) + # comment5 + and + # comment6 + c + or ( + # comment7 + d + ) + ) +): + print("Foo") +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__composition.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__composition.py.snap index 756ef81dd3b62..c1c42e11bbb3d 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__composition.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition_no_trailing_comma.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__composition_no_trailing_comma.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition_no_trailing_comma.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__composition_no_trailing_comma.py.snap index 89664dc7c155b..4888f9a617d8c 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__composition_no_trailing_comma.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__composition_no_trailing_comma.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/composition_no_trailing_comma.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/composition_no_trailing_comma.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__conditional_expression.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__conditional_expression.py.snap new file mode 100644 index 0000000000000..55b4f12034c43 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__conditional_expression.py.snap @@ -0,0 +1,334 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/conditional_expression.py +--- +## Input + +```python +long_kwargs_single_line = my_function( + foo="test, this is a sample value", + bar=some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz, + baz="hello, this is a another value", +) + +multiline_kwargs_indented = my_function( + foo="test, this is a sample value", + bar=some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz, + baz="hello, this is a another value", +) + +imploding_kwargs = my_function( + foo="test, this is a sample value", + bar=a + if foo + else b, + baz="hello, this is a another value", +) + +imploding_line = ( + 1 + if 1 + 1 == 2 + else 0 +) + +exploding_line = "hello this is a slightly long string" if some_long_value_name_foo_bar_baz else "this one is a little shorter" + +positional_argument_test(some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz) + +def weird_default_argument(x=some_long_value_name_foo_bar_baz + if SOME_CONSTANT + else some_fallback_value_foo_bar_baz): + pass + +nested = "hello this is a slightly long string" if (some_long_value_name_foo_bar_baz if + nesting_test_expressions else some_fallback_value_foo_bar_baz) \ + else "this one is a little shorter" + +generator_expression = ( + some_long_value_name_foo_bar_baz if some_boolean_variable else some_fallback_value_foo_bar_baz for some_boolean_variable in some_iterable +) + + +def limit_offset_sql(self, low_mark, high_mark): + """Return LIMIT/OFFSET SQL clause.""" + limit, offset = self._get_limit_offset_params(low_mark, high_mark) + return " ".join( + sql + for sql in ( + "LIMIT %d" % limit if limit else None, + ("OFFSET %d" % offset) if offset else None, + ) + if sql + ) + + +def something(): + clone._iterable_class = ( + NamedValuesListIterable + if named + else FlatValuesListIterable + if flat + else ValuesListIterable + ) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,20 +1,16 @@ + long_kwargs_single_line = my_function( + foo="test, this is a sample value", +- bar=( +- some_long_value_name_foo_bar_baz +- if some_boolean_variable +- else some_fallback_value_foo_bar_baz +- ), ++ bar=some_long_value_name_foo_bar_baz ++ if some_boolean_variable ++ else some_fallback_value_foo_bar_baz, + baz="hello, this is a another value", + ) + + multiline_kwargs_indented = my_function( + foo="test, this is a sample value", +- bar=( +- some_long_value_name_foo_bar_baz +- if some_boolean_variable +- else some_fallback_value_foo_bar_baz +- ), ++ bar=some_long_value_name_foo_bar_baz ++ if some_boolean_variable ++ else some_fallback_value_foo_bar_baz, + baz="hello, this is a another value", + ) + +@@ -40,11 +36,9 @@ + + + def weird_default_argument( +- x=( +- some_long_value_name_foo_bar_baz +- if SOME_CONSTANT +- else some_fallback_value_foo_bar_baz +- ), ++ x=some_long_value_name_foo_bar_baz ++ if SOME_CONSTANT ++ else some_fallback_value_foo_bar_baz, + ): + pass + +@@ -60,11 +54,9 @@ + ) + + generator_expression = ( +- ( +- some_long_value_name_foo_bar_baz +- if some_boolean_variable +- else some_fallback_value_foo_bar_baz +- ) ++ some_long_value_name_foo_bar_baz ++ if some_boolean_variable ++ else some_fallback_value_foo_bar_baz + for some_boolean_variable in some_iterable + ) + +@@ -86,5 +78,7 @@ + clone._iterable_class = ( + NamedValuesListIterable + if named +- else FlatValuesListIterable if flat else ValuesListIterable ++ else FlatValuesListIterable ++ if flat ++ else ValuesListIterable + ) +``` + +## Ruff Output + +```python +long_kwargs_single_line = my_function( + foo="test, this is a sample value", + bar=some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz, + baz="hello, this is a another value", +) + +multiline_kwargs_indented = my_function( + foo="test, this is a sample value", + bar=some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz, + baz="hello, this is a another value", +) + +imploding_kwargs = my_function( + foo="test, this is a sample value", + bar=a if foo else b, + baz="hello, this is a another value", +) + +imploding_line = 1 if 1 + 1 == 2 else 0 + +exploding_line = ( + "hello this is a slightly long string" + if some_long_value_name_foo_bar_baz + else "this one is a little shorter" +) + +positional_argument_test( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz +) + + +def weird_default_argument( + x=some_long_value_name_foo_bar_baz + if SOME_CONSTANT + else some_fallback_value_foo_bar_baz, +): + pass + + +nested = ( + "hello this is a slightly long string" + if ( + some_long_value_name_foo_bar_baz + if nesting_test_expressions + else some_fallback_value_foo_bar_baz + ) + else "this one is a little shorter" +) + +generator_expression = ( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz + for some_boolean_variable in some_iterable +) + + +def limit_offset_sql(self, low_mark, high_mark): + """Return LIMIT/OFFSET SQL clause.""" + limit, offset = self._get_limit_offset_params(low_mark, high_mark) + return " ".join( + sql + for sql in ( + "LIMIT %d" % limit if limit else None, + ("OFFSET %d" % offset) if offset else None, + ) + if sql + ) + + +def something(): + clone._iterable_class = ( + NamedValuesListIterable + if named + else FlatValuesListIterable + if flat + else ValuesListIterable + ) +``` + +## Black Output + +```python +long_kwargs_single_line = my_function( + foo="test, this is a sample value", + bar=( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz + ), + baz="hello, this is a another value", +) + +multiline_kwargs_indented = my_function( + foo="test, this is a sample value", + bar=( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz + ), + baz="hello, this is a another value", +) + +imploding_kwargs = my_function( + foo="test, this is a sample value", + bar=a if foo else b, + baz="hello, this is a another value", +) + +imploding_line = 1 if 1 + 1 == 2 else 0 + +exploding_line = ( + "hello this is a slightly long string" + if some_long_value_name_foo_bar_baz + else "this one is a little shorter" +) + +positional_argument_test( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz +) + + +def weird_default_argument( + x=( + some_long_value_name_foo_bar_baz + if SOME_CONSTANT + else some_fallback_value_foo_bar_baz + ), +): + pass + + +nested = ( + "hello this is a slightly long string" + if ( + some_long_value_name_foo_bar_baz + if nesting_test_expressions + else some_fallback_value_foo_bar_baz + ) + else "this one is a little shorter" +) + +generator_expression = ( + ( + some_long_value_name_foo_bar_baz + if some_boolean_variable + else some_fallback_value_foo_bar_baz + ) + for some_boolean_variable in some_iterable +) + + +def limit_offset_sql(self, low_mark, high_mark): + """Return LIMIT/OFFSET SQL clause.""" + limit, offset = self._get_limit_offset_params(low_mark, high_mark) + return " ".join( + sql + for sql in ( + "LIMIT %d" % limit if limit else None, + ("OFFSET %d" % offset) if offset else None, + ) + if sql + ) + + +def something(): + clone._iterable_class = ( + NamedValuesListIterable + if named + else FlatValuesListIterable if flat else ValuesListIterable + ) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__docstring_no_string_normalization.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__docstring_no_string_normalization.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__docstring_no_string_normalization.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__docstring_no_string_normalization.py.snap index bdc68fe77bcbb..17915fd54dd78 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__docstring_no_string_normalization.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__docstring_no_string_normalization.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_no_string_normalization.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/docstring_no_string_normalization.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__expression.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__expression.py.snap index ea14186d298f3..5b60337c94cda 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__expression.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/expression.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/expression.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff.py.snap index 2df0b531f8ef7..44fe937154f9d 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff4.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff4.py.snap similarity index 96% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff4.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff4.py.snap index 529e50d32cbd2..9162f859213cc 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff4.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff4.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff4.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff4.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff5.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff5.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff5.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff5.py.snap index a531a87c052d4..1346480b808e6 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff5.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtonoff5.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtonoff5.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtonoff5.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtpass_imports.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtpass_imports.py.snap similarity index 96% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtpass_imports.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtpass_imports.py.snap index 8dceca43bc0d5..6a8042f10d6c1 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtpass_imports.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtpass_imports.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtpass_imports.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtpass_imports.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtskip5.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtskip5.py.snap similarity index 96% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtskip5.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtskip5.py.snap index 597ccdeeba38a..325b315501abd 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtskip5.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__fmtskip5.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip5.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/fmtskip5.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__funcdef_return_type_trailing_comma.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__funcdef_return_type_trailing_comma.py.snap new file mode 100644 index 0000000000000..09c380567e951 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__funcdef_return_type_trailing_comma.py.snap @@ -0,0 +1,596 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/funcdef_return_type_trailing_comma.py +--- +## Input + +```python +# normal, short, function definition +def foo(a, b) -> tuple[int, float]: ... + + +# normal, short, function definition w/o return type +def foo(a, b): ... + + +# no splitting +def foo(a: A, b: B) -> list[p, q]: + pass + + +# magic trailing comma in param list +def foo(a, b,): ... + + +# magic trailing comma in nested params in param list +def foo(a, b: tuple[int, float,]): ... + + +# magic trailing comma in return type, no params +def a() -> tuple[ + a, + b, +]: ... + + +# magic trailing comma in return type, params +def foo(a: A, b: B) -> list[ + p, + q, +]: + pass + + +# magic trailing comma in param list and in return type +def foo( + a: a, + b: b, +) -> list[ + a, + a, +]: + pass + + +# long function definition, param list is longer +def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa( + bbbbbbbbbbbbbbbbbb, +) -> cccccccccccccccccccccccccccccc: ... + + +# long function definition, return type is longer +# this should maybe split on rhs? +def aaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbb) -> list[ + Ccccccccccccccccccccccccccccccccccccccccccccccccccc, Dddddd +]: ... + + +# long return type, no param list +def foo() -> list[ + Loooooooooooooooooooooooooooooooooooong, + Loooooooooooooooooooong, + Looooooooooooong, +]: ... + + +# long function name, no param list, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong(): + pass + + +# long function name, no param list +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong() -> ( + list[int, float] +): ... + + +# long function name, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong( + a, b +): ... + + +# unskippable type hint (??) +def foo(a) -> list[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]: # type: ignore + pass + + +def foo(a) -> list[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +]: # abpedeifnore + pass + +def foo(a, b: list[Bad],): ... # type: ignore + +# don't lose any comments (no magic) +def foo( # 1 + a, # 2 + b) -> list[ # 3 + a, # 4 + b]: # 5 + ... # 6 + + +# don't lose any comments (param list magic) +def foo( # 1 + a, # 2 + b,) -> list[ # 3 + a, # 4 + b]: # 5 + ... # 6 + + +# don't lose any comments (return type magic) +def foo( # 1 + a, # 2 + b) -> list[ # 3 + a, # 4 + b,]: # 5 + ... # 6 + + +# don't lose any comments (both magic) +def foo( # 1 + a, # 2 + b,) -> list[ # 3 + a, # 4 + b,]: # 5 + ... # 6 + +# real life example +def SimplePyFn( + context: hl.GeneratorContext, + buffer_input: Buffer[UInt8, 2], + func_input: Buffer[Int32, 2], + float_arg: Scalar[Float32], + offset: int = 0, +) -> tuple[ + Buffer[UInt8, 2], + Buffer[UInt8, 2], +]: ... +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -29,14 +29,18 @@ + + + # magic trailing comma in return type, no params +-def a() -> tuple[ +- a, +- b, +-]: ... ++def a() -> ( ++ tuple[ ++ a, ++ b, ++ ] ++): ... + + + # magic trailing comma in return type, params +-def foo(a: A, b: B) -> list[ ++def foo( ++ a: A, b: B ++) -> list[ + p, + q, + ]: +@@ -68,11 +72,13 @@ + + + # long return type, no param list +-def foo() -> list[ +- Loooooooooooooooooooooooooooooooooooong, +- Loooooooooooooooooooong, +- Looooooooooooong, +-]: ... ++def foo() -> ( ++ list[ ++ Loooooooooooooooooooooooooooooooooooong, ++ Loooooooooooooooooooong, ++ Looooooooooooong, ++ ] ++): ... + + + # long function name, no param list, no return value +@@ -93,7 +99,11 @@ + + + # unskippable type hint (??) +-def foo(a) -> list[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]: # type: ignore ++def foo( ++ a, ++) -> list[ ++ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ++]: # type: ignore + pass + + +@@ -112,7 +122,13 @@ + + + # don't lose any comments (no magic) +-def foo(a, b) -> list[a, b]: # 1 # 2 # 3 # 4 # 5 ++def foo( # 1 ++ a, # 2 ++ b, ++) -> list[ # 3 ++ a, # 4 ++ b, ++]: # 5 + ... # 6 + + +@@ -120,12 +136,18 @@ + def foo( # 1 + a, # 2 + b, +-) -> list[a, b]: # 3 # 4 # 5 ++) -> list[ # 3 ++ a, # 4 ++ b, ++]: # 5 + ... # 6 + + + # don't lose any comments (return type magic) +-def foo(a, b) -> list[ # 1 # 2 # 3 ++def foo( # 1 ++ a, # 2 ++ b, ++) -> list[ # 3 + a, # 4 + b, + ]: # 5 +``` + +## Ruff Output + +```python +# normal, short, function definition +def foo(a, b) -> tuple[int, float]: ... + + +# normal, short, function definition w/o return type +def foo(a, b): ... + + +# no splitting +def foo(a: A, b: B) -> list[p, q]: + pass + + +# magic trailing comma in param list +def foo( + a, + b, +): ... + + +# magic trailing comma in nested params in param list +def foo( + a, + b: tuple[ + int, + float, + ], +): ... + + +# magic trailing comma in return type, no params +def a() -> ( + tuple[ + a, + b, + ] +): ... + + +# magic trailing comma in return type, params +def foo( + a: A, b: B +) -> list[ + p, + q, +]: + pass + + +# magic trailing comma in param list and in return type +def foo( + a: a, + b: b, +) -> list[ + a, + a, +]: + pass + + +# long function definition, param list is longer +def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa( + bbbbbbbbbbbbbbbbbb, +) -> cccccccccccccccccccccccccccccc: ... + + +# long function definition, return type is longer +# this should maybe split on rhs? +def aaaaaaaaaaaaaaaaa( + bbbbbbbbbbbbbbbbbb, +) -> list[Ccccccccccccccccccccccccccccccccccccccccccccccccccc, Dddddd]: ... + + +# long return type, no param list +def foo() -> ( + list[ + Loooooooooooooooooooooooooooooooooooong, + Loooooooooooooooooooong, + Looooooooooooong, + ] +): ... + + +# long function name, no param list, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong(): + pass + + +# long function name, no param list +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong() -> ( + list[int, float] +): ... + + +# long function name, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong( + a, b +): ... + + +# unskippable type hint (??) +def foo( + a, +) -> list[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +]: # type: ignore + pass + + +def foo( + a, +) -> list[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +]: # abpedeifnore + pass + + +def foo( + a, + b: list[Bad], +): ... # type: ignore + + +# don't lose any comments (no magic) +def foo( # 1 + a, # 2 + b, +) -> list[ # 3 + a, # 4 + b, +]: # 5 + ... # 6 + + +# don't lose any comments (param list magic) +def foo( # 1 + a, # 2 + b, +) -> list[ # 3 + a, # 4 + b, +]: # 5 + ... # 6 + + +# don't lose any comments (return type magic) +def foo( # 1 + a, # 2 + b, +) -> list[ # 3 + a, # 4 + b, +]: # 5 + ... # 6 + + +# don't lose any comments (both magic) +def foo( # 1 + a, # 2 + b, +) -> list[ # 3 + a, # 4 + b, +]: # 5 + ... # 6 + + +# real life example +def SimplePyFn( + context: hl.GeneratorContext, + buffer_input: Buffer[UInt8, 2], + func_input: Buffer[Int32, 2], + float_arg: Scalar[Float32], + offset: int = 0, +) -> tuple[ + Buffer[UInt8, 2], + Buffer[UInt8, 2], +]: ... +``` + +## Black Output + +```python +# normal, short, function definition +def foo(a, b) -> tuple[int, float]: ... + + +# normal, short, function definition w/o return type +def foo(a, b): ... + + +# no splitting +def foo(a: A, b: B) -> list[p, q]: + pass + + +# magic trailing comma in param list +def foo( + a, + b, +): ... + + +# magic trailing comma in nested params in param list +def foo( + a, + b: tuple[ + int, + float, + ], +): ... + + +# magic trailing comma in return type, no params +def a() -> tuple[ + a, + b, +]: ... + + +# magic trailing comma in return type, params +def foo(a: A, b: B) -> list[ + p, + q, +]: + pass + + +# magic trailing comma in param list and in return type +def foo( + a: a, + b: b, +) -> list[ + a, + a, +]: + pass + + +# long function definition, param list is longer +def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa( + bbbbbbbbbbbbbbbbbb, +) -> cccccccccccccccccccccccccccccc: ... + + +# long function definition, return type is longer +# this should maybe split on rhs? +def aaaaaaaaaaaaaaaaa( + bbbbbbbbbbbbbbbbbb, +) -> list[Ccccccccccccccccccccccccccccccccccccccccccccccccccc, Dddddd]: ... + + +# long return type, no param list +def foo() -> list[ + Loooooooooooooooooooooooooooooooooooong, + Loooooooooooooooooooong, + Looooooooooooong, +]: ... + + +# long function name, no param list, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong(): + pass + + +# long function name, no param list +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong() -> ( + list[int, float] +): ... + + +# long function name, no return value +def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeeeeeeeeeeeeeery_looooooong( + a, b +): ... + + +# unskippable type hint (??) +def foo(a) -> list[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]: # type: ignore + pass + + +def foo( + a, +) -> list[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +]: # abpedeifnore + pass + + +def foo( + a, + b: list[Bad], +): ... # type: ignore + + +# don't lose any comments (no magic) +def foo(a, b) -> list[a, b]: # 1 # 2 # 3 # 4 # 5 + ... # 6 + + +# don't lose any comments (param list magic) +def foo( # 1 + a, # 2 + b, +) -> list[a, b]: # 3 # 4 # 5 + ... # 6 + + +# don't lose any comments (return type magic) +def foo(a, b) -> list[ # 1 # 2 # 3 + a, # 4 + b, +]: # 5 + ... # 6 + + +# don't lose any comments (both magic) +def foo( # 1 + a, # 2 + b, +) -> list[ # 3 + a, # 4 + b, +]: # 5 + ... # 6 + + +# real life example +def SimplePyFn( + context: hl.GeneratorContext, + buffer_input: Buffer[UInt8, 2], + func_input: Buffer[Int32, 2], + float_arg: Scalar[Float32], + offset: int = 0, +) -> tuple[ + Buffer[UInt8, 2], + Buffer[UInt8, 2], +]: ... +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__function.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__function.py.snap index 317d6c6a188b6..df6fda9a85cac 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__function.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/function.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function2.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__function2.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function2.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__function2.py.snap index 2fc0696b9ba42..f85dbd5fef575 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function2.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__function2.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/function2.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/function2.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__ignore_pyi.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__ignore_pyi.pyi.snap similarity index 78% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__ignore_pyi.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__ignore_pyi.pyi.snap index 9027c47633afd..0d405b5b573a2 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__ignore_pyi.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__ignore_pyi.pyi.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/ignore_pyi.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/ignore_pyi.pyi --- ## Input @@ -32,34 +32,14 @@ def h(): ```diff --- Black +++ Ruff -@@ -1,18 +1,25 @@ - def f(): # type: ignore - ... +@@ -3,7 +3,6 @@ -+ class x: # some comment ... +- + class y: ... # comment --class y: ... # comment - -+class y: -+ ... # comment -+ -+ # whitespace doesn't matter (note the next line has a trailing space and tab) --class z: ... -+class z: -+ ... -+ - - def g(): - # hi - ... - -+ - def h(): - ... - # bye ``` ## Ruff Output @@ -68,25 +48,17 @@ def h(): def f(): # type: ignore ... - class x: # some comment ... - - -class y: - ... # comment - +class y: ... # comment # whitespace doesn't matter (note the next line has a trailing space and tab) -class z: - ... - +class z: ... def g(): # hi ... - def h(): ... # bye diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_basic.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_basic.py.snap new file mode 100644 index 0000000000000..a37d5fec5ad81 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_basic.py.snap @@ -0,0 +1,317 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_basic.py +--- +## Input + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass +def foo2(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass +def foo3(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass +def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass + +# Adding some unformated code covering a wide range of syntaxes. + +if True: + # Incorrectly indented prefix comments. + pass + +import typing +from typing import ( + Any , + ) +class MyClass( object): # Trailing comment with extra leading space. + #NOTE: The following indentation is incorrect: + @decor( 1 * 3 ) + def my_func( arg): + pass + +try: # Trailing comment with extra leading space. + for i in range(10): # Trailing comment with extra leading space. + while condition: + if something: + then_something( ) + elif something_else: + then_something_else( ) +except ValueError as e: + unformatted( ) +finally: + unformatted( ) + +async def test_async_unformatted( ): # Trailing comment with extra leading space. + async for i in some_iter( unformatted ): # Trailing comment with extra leading space. + await asyncio.sleep( 1 ) + async with some_context( unformatted ): + print( "unformatted" ) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,7 +1,17 @@ +-# flags: --line-ranges=5-6 + # NOTE: If you need to modify this file, pay special attention to the --line-ranges= + # flag above as it's formatting specifically these lines. +-def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass ++def foo1( ++ parameter_1, ++ parameter_2, ++ parameter_3, ++ parameter_4, ++ parameter_5, ++ parameter_6, ++ parameter_7, ++): ++ pass ++ ++ + def foo2( + parameter_1, + parameter_2, +@@ -26,38 +36,52 @@ + pass + + +-def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass ++def foo4( ++ parameter_1, ++ parameter_2, ++ parameter_3, ++ parameter_4, ++ parameter_5, ++ parameter_6, ++ parameter_7, ++): ++ pass ++ + + # Adding some unformated code covering a wide range of syntaxes. + + if True: +- # Incorrectly indented prefix comments. +- pass ++ # Incorrectly indented prefix comments. ++ pass ++ ++import typing ++from typing import ( ++ Any, ++) ++ ++ ++class MyClass(object): # Trailing comment with extra leading space. ++ # NOTE: The following indentation is incorrect: ++ @decor(1 * 3) ++ def my_func(arg): ++ pass + +-import typing +-from typing import ( +- Any , +- ) +-class MyClass( object): # Trailing comment with extra leading space. +- #NOTE: The following indentation is incorrect: +- @decor( 1 * 3 ) +- def my_func( arg): +- pass + +-try: # Trailing comment with extra leading space. +- for i in range(10): # Trailing comment with extra leading space. +- while condition: +- if something: +- then_something( ) +- elif something_else: +- then_something_else( ) +-except ValueError as e: +- unformatted( ) ++try: # Trailing comment with extra leading space. ++ for i in range(10): # Trailing comment with extra leading space. ++ while condition: ++ if something: ++ then_something() ++ elif something_else: ++ then_something_else() ++except ValueError as e: ++ unformatted() + finally: +- unformatted( ) ++ unformatted() ++ + +-async def test_async_unformatted( ): # Trailing comment with extra leading space. +- async for i in some_iter( unformatted ): # Trailing comment with extra leading space. +- await asyncio.sleep( 1 ) +- async with some_context( unformatted ): +- print( "unformatted" ) ++async def test_async_unformatted(): # Trailing comment with extra leading space. ++ async for i in some_iter(unformatted): # Trailing comment with extra leading space. ++ await asyncio.sleep(1) ++ async with some_context(unformatted): ++ print("unformatted") +``` + +## Ruff Output + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +def foo1( + parameter_1, + parameter_2, + parameter_3, + parameter_4, + parameter_5, + parameter_6, + parameter_7, +): + pass + + +def foo2( + parameter_1, + parameter_2, + parameter_3, + parameter_4, + parameter_5, + parameter_6, + parameter_7, +): + pass + + +def foo3( + parameter_1, + parameter_2, + parameter_3, + parameter_4, + parameter_5, + parameter_6, + parameter_7, +): + pass + + +def foo4( + parameter_1, + parameter_2, + parameter_3, + parameter_4, + parameter_5, + parameter_6, + parameter_7, +): + pass + + +# Adding some unformated code covering a wide range of syntaxes. + +if True: + # Incorrectly indented prefix comments. + pass + +import typing +from typing import ( + Any, +) + + +class MyClass(object): # Trailing comment with extra leading space. + # NOTE: The following indentation is incorrect: + @decor(1 * 3) + def my_func(arg): + pass + + +try: # Trailing comment with extra leading space. + for i in range(10): # Trailing comment with extra leading space. + while condition: + if something: + then_something() + elif something_else: + then_something_else() +except ValueError as e: + unformatted() +finally: + unformatted() + + +async def test_async_unformatted(): # Trailing comment with extra leading space. + async for i in some_iter(unformatted): # Trailing comment with extra leading space. + await asyncio.sleep(1) + async with some_context(unformatted): + print("unformatted") +``` + +## Black Output + +```python +# flags: --line-ranges=5-6 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass +def foo2( + parameter_1, + parameter_2, + parameter_3, + parameter_4, + parameter_5, + parameter_6, + parameter_7, +): + pass + + +def foo3( + parameter_1, + parameter_2, + parameter_3, + parameter_4, + parameter_5, + parameter_6, + parameter_7, +): + pass + + +def foo4(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, parameter_6, parameter_7): pass + +# Adding some unformated code covering a wide range of syntaxes. + +if True: + # Incorrectly indented prefix comments. + pass + +import typing +from typing import ( + Any , + ) +class MyClass( object): # Trailing comment with extra leading space. + #NOTE: The following indentation is incorrect: + @decor( 1 * 3 ) + def my_func( arg): + pass + +try: # Trailing comment with extra leading space. + for i in range(10): # Trailing comment with extra leading space. + while condition: + if something: + then_something( ) + elif something_else: + then_something_else( ) +except ValueError as e: + unformatted( ) +finally: + unformatted( ) + +async def test_async_unformatted( ): # Trailing comment with extra leading space. + async for i in some_iter( unformatted ): # Trailing comment with extra leading space. + await asyncio.sleep( 1 ) + async with some_context( unformatted ): + print( "unformatted" ) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_diff_edge_case.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_diff_edge_case.py.snap new file mode 100644 index 0000000000000..ee8fb11d45870 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_diff_edge_case.py.snap @@ -0,0 +1,79 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_diff_edge_case.py +--- +## Input + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Reproducible example for https://github.com/psf/black/issues/4033. +# This can be fixed in the future if we use a better diffing algorithm, or make Black +# perform formatting in a single pass. + +print ( "format me" ) +print ( "format me" ) +print ( "format me" ) +print ( "format me" ) +print ( "format me" ) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,4 +1,3 @@ +-# flags: --line-ranges=10-11 + # NOTE: If you need to modify this file, pay special attention to the --line-ranges= + # flag above as it's formatting specifically these lines. + +@@ -6,8 +5,8 @@ + # This can be fixed in the future if we use a better diffing algorithm, or make Black + # perform formatting in a single pass. + +-print ( "format me" ) + print("format me") + print("format me") + print("format me") + print("format me") ++print("format me") +``` + +## Ruff Output + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Reproducible example for https://github.com/psf/black/issues/4033. +# This can be fixed in the future if we use a better diffing algorithm, or make Black +# perform formatting in a single pass. + +print("format me") +print("format me") +print("format me") +print("format me") +print("format me") +``` + +## Black Output + +```python +# flags: --line-ranges=10-11 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Reproducible example for https://github.com/psf/black/issues/4033. +# This can be fixed in the future if we use a better diffing algorithm, or make Black +# perform formatting in a single pass. + +print ( "format me" ) +print("format me") +print("format me") +print("format me") +print("format me") +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off.py.snap new file mode 100644 index 0000000000000..119237fb5d4af --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off.py.snap @@ -0,0 +1,114 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off.py +--- +## Input + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# fmt: off +import os +def myfunc( ): # Intentionally unformatted. + pass +# fmt: on + + +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc( ): # This will be reformatted. + print( {"this will be reformatted"} ) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,4 +1,3 @@ +-# flags: --line-ranges=7-7 --line-ranges=17-23 + # NOTE: If you need to modify this file, pay special attention to the --line-ranges= + # flag above as it's formatting specifically these lines. + +@@ -9,8 +8,10 @@ + # fmt: on + + +-def myfunc( ): # This will not be reformatted. +- print( {"also won't be reformatted"} ) ++def myfunc(): # This will not be reformatted. ++ print({"also won't be reformatted"}) ++ ++ + # fmt: off + def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +``` + +## Ruff Output + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# fmt: off +import os +def myfunc( ): # Intentionally unformatted. + pass +# fmt: on + + +def myfunc(): # This will not be reformatted. + print({"also won't be reformatted"}) + + +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc(): # This will be reformatted. + print({"this will be reformatted"}) +``` + +## Black Output + +```python +# flags: --line-ranges=7-7 --line-ranges=17-23 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# fmt: off +import os +def myfunc( ): # Intentionally unformatted. + pass +# fmt: on + + +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc(): # This will be reformatted. + print({"this will be reformatted"}) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off_decorator.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off_decorator.py.snap new file mode 100644 index 0000000000000..d14b92cc08c31 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off_decorator.py.snap @@ -0,0 +1,110 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_decorator.py +--- +## Input + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Regression test for an edge case involving decorators and fmt: off/on. +class MyClass: + + # fmt: off + @decorator ( ) + # fmt: on + def method(): + print ( "str" ) + + @decor( + a=1, + # fmt: off + b=(2, 3), + # fmt: on + ) + def func(): + pass +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,15 +1,13 @@ +-# flags: --line-ranges=12-12 --line-ranges=21-21 + # NOTE: If you need to modify this file, pay special attention to the --line-ranges= + # flag above as it's formatting specifically these lines. + + # Regression test for an edge case involving decorators and fmt: off/on. + class MyClass: +- + # fmt: off + @decorator ( ) + # fmt: on + def method(): +- print("str") ++ print ( "str" ) + + @decor( + a=1, +@@ -18,4 +16,4 @@ + # fmt: on + ) + def func(): +- pass ++ pass +``` + +## Ruff Output + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Regression test for an edge case involving decorators and fmt: off/on. +class MyClass: + # fmt: off + @decorator ( ) + # fmt: on + def method(): + print ( "str" ) + + @decor( + a=1, + # fmt: off + b=(2, 3), + # fmt: on + ) + def func(): + pass +``` + +## Black Output + +```python +# flags: --line-ranges=12-12 --line-ranges=21-21 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# Regression test for an edge case involving decorators and fmt: off/on. +class MyClass: + + # fmt: off + @decorator ( ) + # fmt: on + def method(): + print("str") + + @decor( + a=1, + # fmt: off + b=(2, 3), + # fmt: on + ) + def func(): + pass +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off_overlap.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off_overlap.py.snap new file mode 100644 index 0000000000000..5130df3f7cd32 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_fmt_off_overlap.py.snap @@ -0,0 +1,93 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_fmt_off_overlap.py +--- +## Input + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + + +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc( ): # This will be reformatted. + print( {"this will be reformatted"} ) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,10 +1,11 @@ +-# flags: --line-ranges=11-17 + # NOTE: If you need to modify this file, pay special attention to the --line-ranges= + # flag above as it's formatting specifically these lines. + + +-def myfunc( ): # This will not be reformatted. +- print( {"also won't be reformatted"} ) ++def myfunc(): # This will not be reformatted. ++ print({"also won't be reformatted"}) ++ ++ + # fmt: off + def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +``` + +## Ruff Output + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + + +def myfunc(): # This will not be reformatted. + print({"also won't be reformatted"}) + + +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc(): # This will be reformatted. + print({"this will be reformatted"}) +``` + +## Black Output + +```python +# flags: --line-ranges=11-17 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + + +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: off +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +def myfunc( ): # This will not be reformatted. + print( {"also won't be reformatted"} ) +# fmt: on + + +def myfunc(): # This will be reformatted. + print({"this will be reformatted"}) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_indentation.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_indentation.py.snap new file mode 100644 index 0000000000000..53fac2515565b --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_indentation.py.snap @@ -0,0 +1,72 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_indentation.py +--- +## Input + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +if cond1: + print("first") + if cond2: + print("second") + else: + print("else") + +if another_cond: + print("will not be changed") +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,4 +1,3 @@ +-# flags: --line-ranges=5-5 + # NOTE: If you need to modify this file, pay special attention to the --line-ranges= + # flag above as it's formatting specifically these lines. + if cond1: +@@ -9,4 +8,4 @@ + print("else") + + if another_cond: +- print("will not be changed") ++ print("will not be changed") +``` + +## Ruff Output + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +if cond1: + print("first") + if cond2: + print("second") + else: + print("else") + +if another_cond: + print("will not be changed") +``` + +## Black Output + +```python +# flags: --line-ranges=5-5 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +if cond1: + print("first") + if cond2: + print("second") + else: + print("else") + +if another_cond: + print("will not be changed") +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_two_passes.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_two_passes.py.snap new file mode 100644 index 0000000000000..b12db8172060f --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_two_passes.py.snap @@ -0,0 +1,77 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_two_passes.py +--- +## Input + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# This is a specific case for Black's two-pass formatting behavior in `format_str`. +# The second pass must respect the line ranges before the first pass. + + +def restrict_to_this_line(arg1, + arg2, + arg3): + print ( "This should not be formatted." ) + print ( "Note that in the second pass, the original line range 9-11 will cover these print lines.") +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,4 +1,3 @@ +-# flags: --line-ranges=9-11 + # NOTE: If you need to modify this file, pay special attention to the --line-ranges= + # flag above as it's formatting specifically these lines. + +@@ -7,5 +6,7 @@ + + + def restrict_to_this_line(arg1, arg2, arg3): +- print ( "This should not be formatted." ) +- print ( "Note that in the second pass, the original line range 9-11 will cover these print lines.") ++ print("This should not be formatted.") ++ print( ++ "Note that in the second pass, the original line range 9-11 will cover these print lines." ++ ) +``` + +## Ruff Output + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# This is a specific case for Black's two-pass formatting behavior in `format_str`. +# The second pass must respect the line ranges before the first pass. + + +def restrict_to_this_line(arg1, arg2, arg3): + print("This should not be formatted.") + print( + "Note that in the second pass, the original line range 9-11 will cover these print lines." + ) +``` + +## Black Output + +```python +# flags: --line-ranges=9-11 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. + +# This is a specific case for Black's two-pass formatting behavior in `format_str`. +# The second pass must respect the line ranges before the first pass. + + +def restrict_to_this_line(arg1, arg2, arg3): + print ( "This should not be formatted." ) + print ( "Note that in the second pass, the original line range 9-11 will cover these print lines.") +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_unwrapping.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_unwrapping.py.snap new file mode 100644 index 0000000000000..02466fbfa2f8a --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__line_ranges_unwrapping.py.snap @@ -0,0 +1,60 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/line_ranges_unwrapping.py +--- +## Input + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +alist = [ + 1, 2 +] + +adict = { + "key" : "value" +} + +func_call ( + arg = value +) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,4 +1,3 @@ +-# flags: --line-ranges=5-5 --line-ranges=9-9 --line-ranges=13-13 + # NOTE: If you need to modify this file, pay special attention to the --line-ranges= + # flag above as it's formatting specifically these lines. + alist = [1, 2] +``` + +## Ruff Output + +```python +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +alist = [1, 2] + +adict = {"key": "value"} + +func_call(arg=value) +``` + +## Black Output + +```python +# flags: --line-ranges=5-5 --line-ranges=9-9 --line-ranges=13-13 +# NOTE: If you need to modify this file, pay special attention to the --line-ranges= +# flag above as it's formatting specifically these lines. +alist = [1, 2] + +adict = {"key": "value"} + +func_call(arg=value) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__long_strings_flag_disabled.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__long_strings_flag_disabled.py.snap index 554b9b0fb365a..47c71cf9a2863 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__long_strings_flag_disabled.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/long_strings_flag_disabled.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/long_strings_flag_disabled.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__multiline_consecutive_open_parentheses_ignore.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__multiline_consecutive_open_parentheses_ignore.py.snap similarity index 95% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__multiline_consecutive_open_parentheses_ignore.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__multiline_consecutive_open_parentheses_ignore.py.snap index 66ce78e5b1d94..45a41abfe2ea4 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__multiline_consecutive_open_parentheses_ignore.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__multiline_consecutive_open_parentheses_ignore.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/multiline_consecutive_open_parentheses_ignore.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/multiline_consecutive_open_parentheses_ignore.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__nested_stub.pyi.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__nested_stub.pyi.snap new file mode 100644 index 0000000000000..9ebdd53453119 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__nested_stub.pyi.snap @@ -0,0 +1,126 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/nested_stub.pyi +--- +## Input + +```python +import sys + +class Outer: + class InnerStub: ... + outer_attr_after_inner_stub: int + class Inner: + inner_attr: int + outer_attr: int + +if sys.version_info > (3, 7): + if sys.platform == "win32": + assignment = 1 + def function_definition(self): ... + def f1(self) -> str: ... + if sys.platform != "win32": + def function_definition(self): ... + assignment = 1 + def f2(self) -> str: ... +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,7 +1,9 @@ + import sys + ++ + class Outer: + class InnerStub: ... ++ + outer_attr_after_inner_stub: int + + class Inner: +@@ -9,14 +11,19 @@ + + outer_attr: int + ++ + if sys.version_info > (3, 7): + if sys.platform == "win32": + assignment = 1 ++ + def function_definition(self): ... + + def f1(self) -> str: ... ++ + if sys.platform != "win32": ++ + def function_definition(self): ... ++ + assignment = 1 + + def f2(self) -> str: ... +``` + +## Ruff Output + +```python +import sys + + +class Outer: + class InnerStub: ... + + outer_attr_after_inner_stub: int + + class Inner: + inner_attr: int + + outer_attr: int + + +if sys.version_info > (3, 7): + if sys.platform == "win32": + assignment = 1 + + def function_definition(self): ... + + def f1(self) -> str: ... + + if sys.platform != "win32": + + def function_definition(self): ... + + assignment = 1 + + def f2(self) -> str: ... +``` + +## Black Output + +```python +import sys + +class Outer: + class InnerStub: ... + outer_attr_after_inner_stub: int + + class Inner: + inner_attr: int + + outer_attr: int + +if sys.version_info > (3, 7): + if sys.platform == "win32": + assignment = 1 + def function_definition(self): ... + + def f1(self) -> str: ... + if sys.platform != "win32": + def function_definition(self): ... + assignment = 1 + + def f2(self) -> str: ... +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pattern_matching_style.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pattern_matching_style.py.snap similarity index 98% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pattern_matching_style.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pattern_matching_style.py.snap index 51669107f8a53..06422b3718754 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pattern_matching_style.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pattern_matching_style.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_style.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/pattern_matching_style.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep604_union_types_line_breaks.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep604_union_types_line_breaks.py.snap new file mode 100644 index 0000000000000..bf6f676be094e --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep604_union_types_line_breaks.py.snap @@ -0,0 +1,364 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep604_union_types_line_breaks.py +--- +## Input + +```python +# This has always worked +z= Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong + +# "AnnAssign"s now also work +z: Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong +z: (Short + | Short2 + | Short3 + | Short4) +z: (int) +z: ((int)) + + +z: Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong = 7 +z: (Short + | Short2 + | Short3 + | Short4) = 8 +z: (int) = 2.3 +z: ((int)) = foo() + +# In case I go for not enforcing parantheses, this might get improved at the same time +x = ( + z + == 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999, + y + == 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999, +) + +x = ( + z == (9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999), + y == (9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999), +) + +# handle formatting of "tname"s in parameter list + +# remove unnecessary paren +def foo(i: (int)) -> None: ... + + +# this is a syntax error in the type annotation according to mypy, but it's not invalid *python* code, so make sure we don't mess with it and make it so. +def foo(i: (int,)) -> None: ... + +def foo( + i: int, + x: Loooooooooooooooooooooooong + | Looooooooooooooooong + | Looooooooooooooooooooong + | Looooooong, + *, + s: str, +) -> None: + pass + + +@app.get("/path/") +async def foo( + q: str + | None = Query(None, title="Some long title", description="Some long description") +): + pass + + +def f( + max_jobs: int + | None = Option( + None, help="Maximum number of jobs to launch. And some additional text." + ), + another_option: bool = False + ): + ... +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -7,23 +7,13 @@ + ) + + # "AnnAssign"s now also work +-z: ( +- Loooooooooooooooooooooooong +- | Loooooooooooooooooooooooong +- | Loooooooooooooooooooooooong +- | Loooooooooooooooooooooooong +-) +-z: Short | Short2 | Short3 | Short4 +-z: int +-z: int ++z: Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong ++z: (Short | Short2 | Short3 | Short4) ++z: (int) ++z: (int) + + +-z: ( +- Loooooooooooooooooooooooong +- | Loooooooooooooooooooooooong +- | Loooooooooooooooooooooooong +- | Loooooooooooooooooooooooong +-) = 7 ++z: Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong = 7 + z: Short | Short2 | Short3 | Short4 = 8 + z: int = 2.3 + z: int = foo() +@@ -63,7 +53,7 @@ + + + # remove unnecessary paren +-def foo(i: int) -> None: ... ++def foo(i: (int)) -> None: ... + + + # this is a syntax error in the type annotation according to mypy, but it's not invalid *python* code, so make sure we don't mess with it and make it so. +@@ -72,12 +62,10 @@ + + def foo( + i: int, +- x: ( +- Loooooooooooooooooooooooong +- | Looooooooooooooooong +- | Looooooooooooooooooooong +- | Looooooong +- ), ++ x: Loooooooooooooooooooooooong ++ | Looooooooooooooooong ++ | Looooooooooooooooooooong ++ | Looooooong, + *, + s: str, + ) -> None: +@@ -88,7 +76,7 @@ + async def foo( + q: str | None = Query( + None, title="Some long title", description="Some long description" +- ) ++ ), + ): + pass + +``` + +## Ruff Output + +```python +# This has always worked +z = ( + Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong +) + +# "AnnAssign"s now also work +z: Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong +z: (Short | Short2 | Short3 | Short4) +z: (int) +z: (int) + + +z: Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong = 7 +z: Short | Short2 | Short3 | Short4 = 8 +z: int = 2.3 +z: int = foo() + +# In case I go for not enforcing parantheses, this might get improved at the same time +x = ( + z + == 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999, + y + == 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999, +) + +x = ( + z + == ( + 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + ), + y + == ( + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + ), +) + +# handle formatting of "tname"s in parameter list + + +# remove unnecessary paren +def foo(i: (int)) -> None: ... + + +# this is a syntax error in the type annotation according to mypy, but it's not invalid *python* code, so make sure we don't mess with it and make it so. +def foo(i: (int,)) -> None: ... + + +def foo( + i: int, + x: Loooooooooooooooooooooooong + | Looooooooooooooooong + | Looooooooooooooooooooong + | Looooooong, + *, + s: str, +) -> None: + pass + + +@app.get("/path/") +async def foo( + q: str | None = Query( + None, title="Some long title", description="Some long description" + ), +): + pass + + +def f( + max_jobs: int | None = Option( + None, help="Maximum number of jobs to launch. And some additional text." + ), + another_option: bool = False, +): ... +``` + +## Black Output + +```python +# This has always worked +z = ( + Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong +) + +# "AnnAssign"s now also work +z: ( + Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong +) +z: Short | Short2 | Short3 | Short4 +z: int +z: int + + +z: ( + Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong + | Loooooooooooooooooooooooong +) = 7 +z: Short | Short2 | Short3 | Short4 = 8 +z: int = 2.3 +z: int = foo() + +# In case I go for not enforcing parantheses, this might get improved at the same time +x = ( + z + == 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999, + y + == 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999, +) + +x = ( + z + == ( + 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + | 9999999999999999999999999999999999999999 + ), + y + == ( + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + + 9999999999999999999999999999999999999999 + ), +) + +# handle formatting of "tname"s in parameter list + + +# remove unnecessary paren +def foo(i: int) -> None: ... + + +# this is a syntax error in the type annotation according to mypy, but it's not invalid *python* code, so make sure we don't mess with it and make it so. +def foo(i: (int,)) -> None: ... + + +def foo( + i: int, + x: ( + Loooooooooooooooooooooooong + | Looooooooooooooooong + | Looooooooooooooooooooong + | Looooooong + ), + *, + s: str, +) -> None: + pass + + +@app.get("/path/") +async def foo( + q: str | None = Query( + None, title="Some long title", description="Some long description" + ) +): + pass + + +def f( + max_jobs: int | None = Option( + None, help="Maximum number of jobs to launch. And some additional text." + ), + another_option: bool = False, +): ... +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pep_572_py310.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep_572_py310.py.snap similarity index 98% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pep_572_py310.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep_572_py310.py.snap index b694f46cfdfaa..a49397f429243 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pep_572_py310.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep_572_py310.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pep_572_py310.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_py310.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_38__pep_572_remove_parens.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep_572_remove_parens.py.snap similarity index 98% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_38__pep_572_remove_parens.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep_572_remove_parens.py.snap index 49c78e65597e9..ac78124cef0f4 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_38__pep_572_remove_parens.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__pep_572_remove_parens.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_38/pep_572_remove_parens.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/pep_572_remove_parens.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__power_op_newline.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__power_op_newline.py.snap similarity index 73% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__power_op_newline.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__power_op_newline.py.snap index b9ff9703eb179..bb1b6eed95ecb 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__power_op_newline.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__power_op_newline.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/power_op_newline.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/power_op_newline.py --- ## Input @@ -13,21 +13,24 @@ importA;()<<0**0# ```diff --- Black +++ Ruff -@@ -1,6 +1,2 @@ - importA --( -- () -- << 0 +@@ -2,5 +2,5 @@ + ( + () + << 0 - ** 0 --) # -+() << 0**0 # ++ **0 + ) # ``` ## Ruff Output ```python importA -() << 0**0 # +( + () + << 0 + **0 +) # ``` ## Black Output diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_allow_empty_first_line_in_special_cases.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_allow_empty_first_line_in_special_cases.py.snap new file mode 100644 index 0000000000000..2dce9bc3af03b --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_allow_empty_first_line_in_special_cases.py.snap @@ -0,0 +1,218 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_allow_empty_first_line_in_special_cases.py +--- +## Input + +```python +def foo(): + """ + Docstring + """ + + # Here we go + if x: + + # This is also now fine + a = 123 + + else: + # But not necessary + a = 123 + + if y: + + while True: + + """ + Long comment here + """ + a = 123 + + if z: + + for _ in range(100): + a = 123 + else: + + try: + + # this should be ok + a = 123 + except: + + """also this""" + a = 123 + + +def bar(): + + if x: + a = 123 + + +def baz(): + + # OK + if x: + a = 123 +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -5,7 +5,6 @@ + + # Here we go + if x: +- + # This is also now fine + a = 123 + +@@ -14,38 +13,30 @@ + a = 123 + + if y: +- + while True: +- + """ + Long comment here + """ + a = 123 + + if z: +- + for _ in range(100): + a = 123 + else: +- + try: +- + # this should be ok + a = 123 + except: +- + """also this""" + a = 123 + + + def bar(): +- + if x: + a = 123 + + + def baz(): +- + # OK + if x: + a = 123 +``` + +## Ruff Output + +```python +def foo(): + """ + Docstring + """ + + # Here we go + if x: + # This is also now fine + a = 123 + + else: + # But not necessary + a = 123 + + if y: + while True: + """ + Long comment here + """ + a = 123 + + if z: + for _ in range(100): + a = 123 + else: + try: + # this should be ok + a = 123 + except: + """also this""" + a = 123 + + +def bar(): + if x: + a = 123 + + +def baz(): + # OK + if x: + a = 123 +``` + +## Black Output + +```python +def foo(): + """ + Docstring + """ + + # Here we go + if x: + + # This is also now fine + a = 123 + + else: + # But not necessary + a = 123 + + if y: + + while True: + + """ + Long comment here + """ + a = 123 + + if z: + + for _ in range(100): + a = 123 + else: + + try: + + # this should be ok + a = 123 + except: + + """also this""" + a = 123 + + +def bar(): + + if x: + a = 123 + + +def baz(): + + # OK + if x: + a = 123 +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_cantfit.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_cantfit.py.snap new file mode 100644 index 0000000000000..c22c4b6ea4a72 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_cantfit.py.snap @@ -0,0 +1,219 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_cantfit.py +--- +## Input + +```python +# long variable name +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 0 +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 1 # with a comment +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = [ + 1, 2, 3 +] +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function() +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + arg1, arg2, arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +# long function name +normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying() +normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + arg1, arg2, arg3 +) +normal_name = but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +# long arguments +normal_name = normal_function_name( + "but with super long string arguments that on their own exceed the line limit so there's no way it can ever fit", + "eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs", + this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it=0, +) +string_variable_name = ( + "a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do" # noqa +) +for key in """ + hostname + port + username +""".split(): + if key in self.connect_kwargs: + raise ValueError(err.format(key)) +concatenated_strings = "some strings that are " "concatenated implicitly, so if you put them on separate " "lines it will fit" +del concatenated_strings, string_variable_name, normal_function_name, normal_name, need_more_to_make_the_line_long_enough +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,18 +1,12 @@ + # long variable name +-this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( +- 0 +-) +-this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( +- 1 # with a comment +-) ++this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 0 ++this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 1 # with a comment + this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = [ + 1, + 2, + 3, + ] +-this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( +- function() +-) ++this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function() + this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + arg1, arg2, arg3 + ) +@@ -35,10 +29,8 @@ + ) + # long arguments + normal_name = normal_function_name( +- "but with super long string arguments that on their own exceed the line limit so" +- " there's no way it can ever fit", +- "eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs" +- " with spam and eggs and spam with eggs", ++ "but with super long string arguments that on their own exceed the line limit so there's no way it can ever fit", ++ "eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs", + this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it=0, + ) + string_variable_name = "a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do" # noqa +``` + +## Ruff Output + +```python +# long variable name +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 0 +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 1 # with a comment +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = [ + 1, + 2, + 3, +] +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function() +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + arg1, arg2, arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +# long function name +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying() +) +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + arg1, arg2, arg3 + ) +) +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 + ) +) +# long arguments +normal_name = normal_function_name( + "but with super long string arguments that on their own exceed the line limit so there's no way it can ever fit", + "eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs", + this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it=0, +) +string_variable_name = "a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do" # noqa +for key in """ + hostname + port + username +""".split(): + if key in self.connect_kwargs: + raise ValueError(err.format(key)) +concatenated_strings = ( + "some strings that are " + "concatenated implicitly, so if you put them on separate " + "lines it will fit" +) +del ( + concatenated_strings, + string_variable_name, + normal_function_name, + normal_name, + need_more_to_make_the_line_long_enough, +) +``` + +## Black Output + +```python +# long variable name +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( + 0 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( + 1 # with a comment +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = [ + 1, + 2, + 3, +] +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( + function() +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + arg1, arg2, arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +# long function name +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying() +) +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + arg1, arg2, arg3 + ) +) +normal_name = ( + but_the_function_name_is_now_ridiculously_long_and_it_is_still_super_annoying( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 + ) +) +# long arguments +normal_name = normal_function_name( + "but with super long string arguments that on their own exceed the line limit so" + " there's no way it can ever fit", + "eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs" + " with spam and eggs and spam with eggs", + this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it=0, +) +string_variable_name = "a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do" # noqa +for key in """ + hostname + port + username +""".split(): + if key in self.connect_kwargs: + raise ValueError(err.format(key)) +concatenated_strings = ( + "some strings that are " + "concatenated implicitly, so if you put them on separate " + "lines it will fit" +) +del ( + concatenated_strings, + string_variable_name, + normal_function_name, + normal_name, + need_more_to_make_the_line_long_enough, +) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_comments7.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_comments7.py.snap new file mode 100644 index 0000000000000..337c78698d551 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_comments7.py.snap @@ -0,0 +1,600 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_comments7.py +--- +## Input + +```python +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + Path, + # String, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) + + +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + no_comma_here_yet + # and some comments, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent # NOT DRY +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent as component # DRY +) + + +result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +result = ( + 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +) + +result = ( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa +) + +result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa + + +def func(): + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0789, + a[-1], # type: ignore + ) + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0789, + a[-1] # type: ignore + ) + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + a[-1] # type: ignore + ) + + # The type: ignore exception only applies to line length, not + # other types of formatting. + c = call( + "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", # type: ignore + "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa" + ) + + +class C: + @pytest.mark.parametrize( + ("post_data", "message"), + [ + # metadata_version errors. + ( + {}, + "None is an invalid value for Metadata-Version. Error: This field is" + " required. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ( + {"metadata_version": "-1"}, + "'-1' is an invalid value for Metadata-Version. Error: Unknown Metadata" + " Version see" + " https://packaging.python.org/specifications/core-metadata" + ), + # name errors. + ( + {"metadata_version": "1.2"}, + "'' is an invalid value for Name. Error: This field is required. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ( + {"metadata_version": "1.2", "name": "foo-"}, + "'foo-' is an invalid value for Name. Error: Must start and end with a" + " letter or numeral and contain only ascii numeric and '.', '_' and" + " '-'. see https://packaging.python.org/specifications/core-metadata" + ), + # version errors. + ( + {"metadata_version": "1.2", "name": "example"}, + "'' is an invalid value for Version. Error: This field is required. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ( + {"metadata_version": "1.2", "name": "example", "version": "dog"}, + "'dog' is an invalid value for Version. Error: Must start and end with" + " a letter or numeral and contain only ascii numeric and '.', '_' and" + " '-'. see https://packaging.python.org/specifications/core-metadata" + ) + ] + ) + def test_fails_invalid_post_data( + self, pyramid_config, db_request, post_data, message + ): + ... + +square = Square(4) # type: Optional[Square] + +# Regression test for https://github.com/psf/black/issues/3756. +[ + ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), +] +[ + ( # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), +] +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -34,13 +34,9 @@ + + result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +-result = ( # aaa +- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +-) ++result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa + +-result = ( # aaa +- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +-) ++result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa + + + def func(): +@@ -52,12 +48,19 @@ + 0.0789, + a[-1], # type: ignore + ) +- c = call(0.0123, 0.0456, 0.0789, 0.0123, 0.0789, a[-1]) # type: ignore + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, ++ 0.0789, ++ a[-1], # type: ignore ++ ) ++ c = call( ++ 0.0123, ++ 0.0456, ++ 0.0789, ++ 0.0123, + 0.0456, + 0.0789, + 0.0123, +@@ -91,53 +94,39 @@ + # metadata_version errors. + ( + {}, +- ( +- "None is an invalid value for Metadata-Version. Error: This field" +- " is required. see" +- " https://packaging.python.org/specifications/core-metadata" +- ), ++ "None is an invalid value for Metadata-Version. Error: This field is" ++ " required. see" ++ " https://packaging.python.org/specifications/core-metadata", + ), + ( + {"metadata_version": "-1"}, +- ( +- "'-1' is an invalid value for Metadata-Version. Error: Unknown" +- " Metadata Version see" +- " https://packaging.python.org/specifications/core-metadata" +- ), ++ "'-1' is an invalid value for Metadata-Version. Error: Unknown Metadata" ++ " Version see" ++ " https://packaging.python.org/specifications/core-metadata", + ), + # name errors. + ( + {"metadata_version": "1.2"}, +- ( +- "'' is an invalid value for Name. Error: This field is required." +- " see https://packaging.python.org/specifications/core-metadata" +- ), ++ "'' is an invalid value for Name. Error: This field is required. see" ++ " https://packaging.python.org/specifications/core-metadata", + ), + ( + {"metadata_version": "1.2", "name": "foo-"}, +- ( +- "'foo-' is an invalid value for Name. Error: Must start and end" +- " with a letter or numeral and contain only ascii numeric and '.'," +- " '_' and '-'. see" +- " https://packaging.python.org/specifications/core-metadata" +- ), ++ "'foo-' is an invalid value for Name. Error: Must start and end with a" ++ " letter or numeral and contain only ascii numeric and '.', '_' and" ++ " '-'. see https://packaging.python.org/specifications/core-metadata", + ), + # version errors. + ( + {"metadata_version": "1.2", "name": "example"}, +- ( +- "'' is an invalid value for Version. Error: This field is required." +- " see https://packaging.python.org/specifications/core-metadata" +- ), ++ "'' is an invalid value for Version. Error: This field is required. see" ++ " https://packaging.python.org/specifications/core-metadata", + ), + ( + {"metadata_version": "1.2", "name": "example", "version": "dog"}, +- ( +- "'dog' is an invalid value for Version. Error: Must start and end" +- " with a letter or numeral and contain only ascii numeric and '.'," +- " '_' and '-'. see" +- " https://packaging.python.org/specifications/core-metadata" +- ), ++ "'dog' is an invalid value for Version. Error: Must start and end with" ++ " a letter or numeral and contain only ascii numeric and '.', '_' and" ++ " '-'. see https://packaging.python.org/specifications/core-metadata", + ), + ], + ) +@@ -150,8 +139,8 @@ + + # Regression test for https://github.com/psf/black/issues/3756. + [ +- ( # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ++ ( ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), + ] + [ +``` + +## Ruff Output + +```python +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + Path, + # String, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) + + +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + no_comma_here_yet, + # and some comments, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent, # NOT DRY +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent as component, # DRY +) + + +result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa + +result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa + + +def func(): + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0789, + a[-1], # type: ignore + ) + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0789, + a[-1], # type: ignore + ) + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + a[-1], # type: ignore + ) + + # The type: ignore exception only applies to line length, not + # other types of formatting. + c = call( + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", # type: ignore + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + ) + + +class C: + @pytest.mark.parametrize( + ("post_data", "message"), + [ + # metadata_version errors. + ( + {}, + "None is an invalid value for Metadata-Version. Error: This field is" + " required. see" + " https://packaging.python.org/specifications/core-metadata", + ), + ( + {"metadata_version": "-1"}, + "'-1' is an invalid value for Metadata-Version. Error: Unknown Metadata" + " Version see" + " https://packaging.python.org/specifications/core-metadata", + ), + # name errors. + ( + {"metadata_version": "1.2"}, + "'' is an invalid value for Name. Error: This field is required. see" + " https://packaging.python.org/specifications/core-metadata", + ), + ( + {"metadata_version": "1.2", "name": "foo-"}, + "'foo-' is an invalid value for Name. Error: Must start and end with a" + " letter or numeral and contain only ascii numeric and '.', '_' and" + " '-'. see https://packaging.python.org/specifications/core-metadata", + ), + # version errors. + ( + {"metadata_version": "1.2", "name": "example"}, + "'' is an invalid value for Version. Error: This field is required. see" + " https://packaging.python.org/specifications/core-metadata", + ), + ( + {"metadata_version": "1.2", "name": "example", "version": "dog"}, + "'dog' is an invalid value for Version. Error: Must start and end with" + " a letter or numeral and contain only ascii numeric and '.', '_' and" + " '-'. see https://packaging.python.org/specifications/core-metadata", + ), + ], + ) + def test_fails_invalid_post_data( + self, pyramid_config, db_request, post_data, message + ): ... + + +square = Square(4) # type: Optional[Square] + +# Regression test for https://github.com/psf/black/issues/3756. +[ + ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), +] +[ + ( # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), +] +``` + +## Black Output + +```python +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + Path, + # String, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) + + +from .config import ( + Any, + Bool, + ConfigType, + ConfigTypeAttributes, + Int, + no_comma_here_yet, + # and some comments, + # resolve_to_config_type, + # DEFAULT_TYPE_ATTRIBUTES, +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent, # NOT DRY +) +from com.my_lovely_company.my_lovely_team.my_lovely_project.my_lovely_component import ( + MyLovelyCompanyTeamProjectComponent as component, # DRY +) + + +result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +result = 1 # look ma, no comment migration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +result = ( # aaa + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + +result = ( # aaa + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + + +def func(): + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0789, + a[-1], # type: ignore + ) + c = call(0.0123, 0.0456, 0.0789, 0.0123, 0.0789, a[-1]) # type: ignore + c = call( + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + 0.0123, + 0.0456, + 0.0789, + a[-1], # type: ignore + ) + + # The type: ignore exception only applies to line length, not + # other types of formatting. + c = call( + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", # type: ignore + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + "aaaaaaaa", + ) + + +class C: + @pytest.mark.parametrize( + ("post_data", "message"), + [ + # metadata_version errors. + ( + {}, + ( + "None is an invalid value for Metadata-Version. Error: This field" + " is required. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ), + ( + {"metadata_version": "-1"}, + ( + "'-1' is an invalid value for Metadata-Version. Error: Unknown" + " Metadata Version see" + " https://packaging.python.org/specifications/core-metadata" + ), + ), + # name errors. + ( + {"metadata_version": "1.2"}, + ( + "'' is an invalid value for Name. Error: This field is required." + " see https://packaging.python.org/specifications/core-metadata" + ), + ), + ( + {"metadata_version": "1.2", "name": "foo-"}, + ( + "'foo-' is an invalid value for Name. Error: Must start and end" + " with a letter or numeral and contain only ascii numeric and '.'," + " '_' and '-'. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ), + # version errors. + ( + {"metadata_version": "1.2", "name": "example"}, + ( + "'' is an invalid value for Version. Error: This field is required." + " see https://packaging.python.org/specifications/core-metadata" + ), + ), + ( + {"metadata_version": "1.2", "name": "example", "version": "dog"}, + ( + "'dog' is an invalid value for Version. Error: Must start and end" + " with a letter or numeral and contain only ascii numeric and '.'," + " '_' and '-'. see" + " https://packaging.python.org/specifications/core-metadata" + ), + ), + ], + ) + def test_fails_invalid_post_data( + self, pyramid_config, db_request, post_data, message + ): ... + + +square = Square(4) # type: Optional[Square] + +# Regression test for https://github.com/psf/black/issues/3756. +[ + ( # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ), +] +[ + ( # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ), +] +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_39.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_39.py.snap new file mode 100644 index 0000000000000..ed87cfaba128d --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_39.py.snap @@ -0,0 +1,342 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_39.py +--- +## Input + +```python +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass + + +# Leading comment +with \ + make_context_manager1() as cm1, \ + make_context_manager2(), \ + make_context_manager3() as cm3, \ + make_context_manager4() \ +: + pass + + +with \ + new_new_new1() as cm1, \ + new_new_new2() \ +: + pass + + +with ( + new_new_new1() as cm1, + new_new_new2() +): + pass + + +# Leading comment. +with ( + # First comment. + new_new_new1() as cm1, + # Second comment. + new_new_new2() + # Last comment. +): + pass + + +with \ + this_is_a_very_long_call(looong_arg1=looong_value1, looong_arg2=looong_value2) as cm1, \ + this_is_a_very_long_call(looong_arg1=looong_value1, looong_arg2=looong_value2, looong_arg3=looong_value3, looong_arg4=looong_value4) as cm2 \ +: + pass + + +with mock.patch.object( + self.my_runner, "first_method", autospec=True +) as mock_run_adb, mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" +): + pass + + +with xxxxxxxx.some_kind_of_method( + some_argument=[ + "first", + "second", + "third", + ] +).another_method() as cmd: + pass + + +async def func(): + async with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ + : + pass + + async with some_function( + argument1, argument2, argument3="some_value" + ) as some_cm, some_other_function( + argument1, argument2, argument3="some_value" + ): + pass +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,19 +1,9 @@ +-with ( +- make_context_manager1() as cm1, +- make_context_manager2() as cm2, +- make_context_manager3() as cm3, +- make_context_manager4() as cm4, +-): ++with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass + + + # Leading comment +-with ( +- make_context_manager1() as cm1, +- make_context_manager2(), +- make_context_manager3() as cm3, +- make_context_manager4(), +-): ++with make_context_manager1() as cm1, make_context_manager2(), make_context_manager3() as cm3, make_context_manager4(): + pass + + +@@ -36,25 +26,21 @@ + pass + + +-with ( +- this_is_a_very_long_call( +- looong_arg1=looong_value1, looong_arg2=looong_value2 +- ) as cm1, +- this_is_a_very_long_call( +- looong_arg1=looong_value1, +- looong_arg2=looong_value2, +- looong_arg3=looong_value3, +- looong_arg4=looong_value4, +- ) as cm2, +-): ++with this_is_a_very_long_call( ++ looong_arg1=looong_value1, looong_arg2=looong_value2 ++) as cm1, this_is_a_very_long_call( ++ looong_arg1=looong_value1, ++ looong_arg2=looong_value2, ++ looong_arg3=looong_value3, ++ looong_arg4=looong_value4, ++) as cm2: + pass + + +-with ( +- mock.patch.object(self.my_runner, "first_method", autospec=True) as mock_run_adb, +- mock.patch.object( +- self.my_runner, "second_method", autospec=True, return_value="foo" +- ), ++with mock.patch.object( ++ self.my_runner, "first_method", autospec=True ++) as mock_run_adb, mock.patch.object( ++ self.my_runner, "second_method", autospec=True, return_value="foo" + ): + pass + +@@ -70,16 +56,10 @@ + + + async def func(): +- async with ( +- make_context_manager1() as cm1, +- make_context_manager2() as cm2, +- make_context_manager3() as cm3, +- make_context_manager4() as cm4, +- ): ++ async with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass + +- async with ( +- some_function(argument1, argument2, argument3="some_value") as some_cm, +- some_other_function(argument1, argument2, argument3="some_value"), +- ): ++ async with some_function( ++ argument1, argument2, argument3="some_value" ++ ) as some_cm, some_other_function(argument1, argument2, argument3="some_value"): + pass +``` + +## Ruff Output + +```python +with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass + + +# Leading comment +with make_context_manager1() as cm1, make_context_manager2(), make_context_manager3() as cm3, make_context_manager4(): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass + + +# Leading comment. +with ( + # First comment. + new_new_new1() as cm1, + # Second comment. + new_new_new2(), + # Last comment. +): + pass + + +with this_is_a_very_long_call( + looong_arg1=looong_value1, looong_arg2=looong_value2 +) as cm1, this_is_a_very_long_call( + looong_arg1=looong_value1, + looong_arg2=looong_value2, + looong_arg3=looong_value3, + looong_arg4=looong_value4, +) as cm2: + pass + + +with mock.patch.object( + self.my_runner, "first_method", autospec=True +) as mock_run_adb, mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" +): + pass + + +with xxxxxxxx.some_kind_of_method( + some_argument=[ + "first", + "second", + "third", + ] +).another_method() as cmd: + pass + + +async def func(): + async with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass + + async with some_function( + argument1, argument2, argument3="some_value" + ) as some_cm, some_other_function(argument1, argument2, argument3="some_value"): + pass +``` + +## Black Output + +```python +with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, +): + pass + + +# Leading comment +with ( + make_context_manager1() as cm1, + make_context_manager2(), + make_context_manager3() as cm3, + make_context_manager4(), +): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass + + +# Leading comment. +with ( + # First comment. + new_new_new1() as cm1, + # Second comment. + new_new_new2(), + # Last comment. +): + pass + + +with ( + this_is_a_very_long_call( + looong_arg1=looong_value1, looong_arg2=looong_value2 + ) as cm1, + this_is_a_very_long_call( + looong_arg1=looong_value1, + looong_arg2=looong_value2, + looong_arg3=looong_value3, + looong_arg4=looong_value4, + ) as cm2, +): + pass + + +with ( + mock.patch.object(self.my_runner, "first_method", autospec=True) as mock_run_adb, + mock.patch.object( + self.my_runner, "second_method", autospec=True, return_value="foo" + ), +): + pass + + +with xxxxxxxx.some_kind_of_method( + some_argument=[ + "first", + "second", + "third", + ] +).another_method() as cmd: + pass + + +async def func(): + async with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, + ): + pass + + async with ( + some_function(argument1, argument2, argument3="some_value") as some_cm, + some_other_function(argument1, argument2, argument3="some_value"), + ): + pass +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_310.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_310.py.snap new file mode 100644 index 0000000000000..abee1610d434c --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_310.py.snap @@ -0,0 +1,79 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_310.py +--- +## Input + +```python +# This file uses pattern matching introduced in Python 3.10. + + +match http_code: + case 404: + print("Not found") + + +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -6,10 +6,5 @@ + print("Not found") + + +-with ( +- make_context_manager1() as cm1, +- make_context_manager2() as cm2, +- make_context_manager3() as cm3, +- make_context_manager4() as cm4, +-): ++with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass +``` + +## Ruff Output + +```python +# This file uses pattern matching introduced in Python 3.10. + + +match http_code: + case 404: + print("Not found") + + +with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass +``` + +## Black Output + +```python +# This file uses pattern matching introduced in Python 3.10. + + +match http_code: + case 404: + print("Not found") + + +with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, +): + pass +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_311.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_311.py.snap new file mode 100644 index 0000000000000..71002c8d5d700 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_311.py.snap @@ -0,0 +1,82 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_311.py +--- +## Input + +```python +# This file uses except* clause in Python 3.11. + + +try: + some_call() +except* Error as e: + pass + + +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -7,10 +7,5 @@ + pass + + +-with ( +- make_context_manager1() as cm1, +- make_context_manager2() as cm2, +- make_context_manager3() as cm3, +- make_context_manager4() as cm4, +-): ++with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass +``` + +## Ruff Output + +```python +# This file uses except* clause in Python 3.11. + + +try: + some_call() +except* Error as e: + pass + + +with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass +``` + +## Black Output + +```python +# This file uses except* clause in Python 3.11. + + +try: + some_call() +except* Error as e: + pass + + +with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, +): + pass +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_39.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_39.py.snap new file mode 100644 index 0000000000000..e1aeaa9faf8b9 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_context_managers_autodetect_39.py.snap @@ -0,0 +1,81 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_context_managers_autodetect_39.py +--- +## Input + +```python +# This file uses parenthesized context managers introduced in Python 3.9. + + +with \ + make_context_manager1() as cm1, \ + make_context_manager2() as cm2, \ + make_context_manager3() as cm3, \ + make_context_manager4() as cm4 \ +: + pass + + +with ( + new_new_new1() as cm1, + new_new_new2() +): + pass +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,12 +1,7 @@ + # This file uses parenthesized context managers introduced in Python 3.9. + + +-with ( +- make_context_manager1() as cm1, +- make_context_manager2() as cm2, +- make_context_manager3() as cm3, +- make_context_manager4() as cm4, +-): ++with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass + + +``` + +## Ruff Output + +```python +# This file uses parenthesized context managers introduced in Python 3.9. + + +with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4: + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass +``` + +## Black Output + +```python +# This file uses parenthesized context managers introduced in Python 3.9. + + +with ( + make_context_manager1() as cm1, + make_context_manager2() as cm2, + make_context_manager3() as cm3, + make_context_manager4() as cm4, +): + pass + + +with new_new_new1() as cm1, new_new_new2(): + pass +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__docstring_preview_no_string_normalization.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_docstring_no_string_normalization.py.snap similarity index 96% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__docstring_preview_no_string_normalization.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_docstring_no_string_normalization.py.snap index a2969f3e403b4..70b323e49317e 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__docstring_preview_no_string_normalization.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_docstring_no_string_normalization.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/docstring_preview_no_string_normalization.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_docstring_no_string_normalization.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_dummy_implementations.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_dummy_implementations.py.snap new file mode 100644 index 0000000000000..a5ec909765730 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_dummy_implementations.py.snap @@ -0,0 +1,231 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_dummy_implementations.py +--- +## Input + +```python +from typing import NoReturn, Protocol, Union, overload + + +def dummy(a): ... +def other(b): ... + + +@overload +def a(arg: int) -> int: ... +@overload +def a(arg: str) -> str: ... +@overload +def a(arg: object) -> NoReturn: ... +def a(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg + +class Proto(Protocol): + def foo(self, a: int) -> int: + ... + + def bar(self, b: str) -> str: ... + def baz(self, c: bytes) -> str: + ... + + +def dummy_two(): + ... +@dummy +def dummy_three(): + ... + +def dummy_four(): + ... + +@overload +def b(arg: int) -> int: ... + +@overload +def b(arg: str) -> str: ... +@overload +def b(arg: object) -> NoReturn: ... + +def b(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -2,15 +2,23 @@ + + + def dummy(a): ... ++ ++ + def other(b): ... + + + @overload + def a(arg: int) -> int: ... ++ ++ + @overload + def a(arg: str) -> str: ... ++ ++ + @overload + def a(arg: object) -> NoReturn: ... ++ ++ + def a(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError +@@ -21,10 +29,13 @@ + def foo(self, a: int) -> int: ... + + def bar(self, b: str) -> str: ... ++ + def baz(self, c: bytes) -> str: ... + + + def dummy_two(): ... ++ ++ + @dummy + def dummy_three(): ... + +@@ -38,6 +49,8 @@ + + @overload + def b(arg: str) -> str: ... ++ ++ + @overload + def b(arg: object) -> NoReturn: ... + +``` + +## Ruff Output + +```python +from typing import NoReturn, Protocol, Union, overload + + +def dummy(a): ... + + +def other(b): ... + + +@overload +def a(arg: int) -> int: ... + + +@overload +def a(arg: str) -> str: ... + + +@overload +def a(arg: object) -> NoReturn: ... + + +def a(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg + + +class Proto(Protocol): + def foo(self, a: int) -> int: ... + + def bar(self, b: str) -> str: ... + + def baz(self, c: bytes) -> str: ... + + +def dummy_two(): ... + + +@dummy +def dummy_three(): ... + + +def dummy_four(): ... + + +@overload +def b(arg: int) -> int: ... + + +@overload +def b(arg: str) -> str: ... + + +@overload +def b(arg: object) -> NoReturn: ... + + +def b(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg +``` + +## Black Output + +```python +from typing import NoReturn, Protocol, Union, overload + + +def dummy(a): ... +def other(b): ... + + +@overload +def a(arg: int) -> int: ... +@overload +def a(arg: str) -> str: ... +@overload +def a(arg: object) -> NoReturn: ... +def a(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg + + +class Proto(Protocol): + def foo(self, a: int) -> int: ... + + def bar(self, b: str) -> str: ... + def baz(self, c: bytes) -> str: ... + + +def dummy_two(): ... +@dummy +def dummy_three(): ... + + +def dummy_four(): ... + + +@overload +def b(arg: int) -> int: ... + + +@overload +def b(arg: str) -> str: ... +@overload +def b(arg: object) -> NoReturn: ... + + +def b(arg: Union[int, str, object]) -> Union[int, str]: + if not isinstance(arg, (int, str)): + raise TypeError + return arg +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_form_feeds.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_form_feeds.py.snap new file mode 100644 index 0000000000000..ae94587cd425e --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_form_feeds.py.snap @@ -0,0 +1,446 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_form_feeds.py +--- +## Input + +```python +# Warning! This file contains form feeds (ASCII 0x0C, often represented by \f or ^L). +# These may be invisible in your editor: ensure you can see them before making changes here. + +# There's one at the start that'll get stripped + +# Comment and statement processing is different enough that we'll test variations of both +# contexts here + +# + + +# + + +# + + + +# + + + +# + + + +# + + +# + + + +# + +# + +# + + \ +# +pass + +pass + + +pass + + +pass + + + +pass + + + +pass + + + +pass + + +pass + + + +pass + +pass + +pass + + +# form feed after a dedent +def foo(): + pass + +pass + + +# form feeds are prohibited inside blocks, or on a line with nonwhitespace + def bar( a = 1 ,b : bool = False ) : + + + pass + + +class Baz: + + def __init__(self): + pass + + + def something(self): + pass + + + +# +pass +pass # +a = 1 + # + pass + a = 1 + +a = [ + +] + +# as internal whitespace of a comment is allowed but why +"form feed literal in a string is okay " + +# form feeds at the very end get removed. +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -5,62 +5,62 @@ + + # Comment and statement processing is different enough that we'll test variations of both + # contexts here +- ++ + # + +- ++ + # + +- ++ + # + +- ++ + # + +- ++ + # + +- ++ + # + +- ++ + # + +- ++ + # +- ++ + # +- ++ + # + + # + pass +- ++ + pass + +- ++ + pass + +- ++ + pass + +- ++ + pass + +- ++ + pass + +- ++ + pass + +- ++ + pass + +- ++ + pass +- ++ + pass +- ++ + pass + + +@@ -68,7 +68,7 @@ + def foo(): + pass + +- ++ + pass + + +@@ -84,7 +84,7 @@ + def something(self): + pass + +- ++ + # + pass + pass # +``` + +## Ruff Output + +```python +# Warning! This file contains form feeds (ASCII 0x0C, often represented by \f or ^L). +# These may be invisible in your editor: ensure you can see them before making changes here. + +# There's one at the start that'll get stripped + +# Comment and statement processing is different enough that we'll test variations of both +# contexts here + +# + + +# + + +# + + +# + + +# + + +# + + +# + + +# + +# + +# + +# +pass + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + +pass + +pass + + +# form feed after a dedent +def foo(): + pass + + +pass + + +# form feeds are prohibited inside blocks, or on a line with nonwhitespace +def bar(a=1, b: bool = False): + pass + + +class Baz: + def __init__(self): + pass + + def something(self): + pass + + +# +pass +pass # +a = 1 +# +pass +a = 1 + +a = [] + +# as internal whitespace of a comment is allowed but why +"form feed literal in a string is okay " + +# form feeds at the very end get removed. +``` + +## Black Output + +```python +# Warning! This file contains form feeds (ASCII 0x0C, often represented by \f or ^L). +# These may be invisible in your editor: ensure you can see them before making changes here. + +# There's one at the start that'll get stripped + +# Comment and statement processing is different enough that we'll test variations of both +# contexts here + +# + + +# + + +# + + +# + + +# + + +# + + +# + + +# + +# + +# + +# +pass + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + + +pass + +pass + +pass + + +# form feed after a dedent +def foo(): + pass + + +pass + + +# form feeds are prohibited inside blocks, or on a line with nonwhitespace +def bar(a=1, b: bool = False): + pass + + +class Baz: + def __init__(self): + pass + + def something(self): + pass + + +# +pass +pass # +a = 1 +# +pass +a = 1 + +a = [] + +# as internal whitespace of a comment is allowed but why +"form feed literal in a string is okay " + +# form feeds at the very end get removed. +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_format_unicode_escape_seq.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_format_unicode_escape_seq.py.snap new file mode 100644 index 0000000000000..c523ecc557c70 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_format_unicode_escape_seq.py.snap @@ -0,0 +1,97 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_format_unicode_escape_seq.py +--- +## Input + +```python +x = "\x1F" +x = "\\x1B" +x = "\\\x1B" +x = "\U0001F60E" +x = "\u0001F60E" +x = r"\u0001F60E" +x = "don't format me" +x = "\xA3" +x = "\u2717" +x = "\uFaCe" +x = "\N{ox}\N{OX}" +x = "\N{lAtIn smaLL letteR x}" +x = "\N{CYRILLIC small LETTER BYELORUSSIAN-UKRAINIAN I}" +x = b"\x1Fdon't byte" +x = rb"\x1Fdon't format" +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,15 +1,15 @@ +-x = "\x1f" ++x = "\x1F" + x = "\\x1B" +-x = "\\\x1b" +-x = "\U0001f60e" ++x = "\\\x1B" ++x = "\U0001F60E" + x = "\u0001F60E" + x = r"\u0001F60E" + x = "don't format me" +-x = "\xa3" ++x = "\xA3" + x = "\u2717" +-x = "\uface" +-x = "\N{OX}\N{OX}" +-x = "\N{LATIN SMALL LETTER X}" +-x = "\N{CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I}" +-x = b"\x1fdon't byte" ++x = "\uFaCe" ++x = "\N{ox}\N{OX}" ++x = "\N{lAtIn smaLL letteR x}" ++x = "\N{CYRILLIC small LETTER BYELORUSSIAN-UKRAINIAN I}" ++x = b"\x1Fdon't byte" + x = rb"\x1Fdon't format" +``` + +## Ruff Output + +```python +x = "\x1F" +x = "\\x1B" +x = "\\\x1B" +x = "\U0001F60E" +x = "\u0001F60E" +x = r"\u0001F60E" +x = "don't format me" +x = "\xA3" +x = "\u2717" +x = "\uFaCe" +x = "\N{ox}\N{OX}" +x = "\N{lAtIn smaLL letteR x}" +x = "\N{CYRILLIC small LETTER BYELORUSSIAN-UKRAINIAN I}" +x = b"\x1Fdon't byte" +x = rb"\x1Fdon't format" +``` + +## Black Output + +```python +x = "\x1f" +x = "\\x1B" +x = "\\\x1b" +x = "\U0001f60e" +x = "\u0001F60E" +x = r"\u0001F60E" +x = "don't format me" +x = "\xa3" +x = "\u2717" +x = "\uface" +x = "\N{OX}\N{OX}" +x = "\N{LATIN SMALL LETTER X}" +x = "\N{CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I}" +x = b"\x1fdon't byte" +x = rb"\x1Fdon't format" +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_hug_parens_with_braces_and_square_brackets.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_hug_parens_with_braces_and_square_brackets.py.snap new file mode 100644 index 0000000000000..e28ce63ff0fea --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_hug_parens_with_braces_and_square_brackets.py.snap @@ -0,0 +1,990 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_hug_parens_with_braces_and_square_brackets.py +--- +## Input + +```python +def foo_brackets(request): + return JsonResponse( + { + "var_1": foo, + "var_2": bar, + } + ) + +def foo_square_brackets(request): + return JsonResponse( + [ + "var_1", + "var_2", + ] + ) + +func({"a": 37, "b": 42, "c": 927, "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111}) + +func(["random_string_number_one","random_string_number_two","random_string_number_three","random_string_number_four"]) + +func( + { + # expand me + 'a':37, + 'b':42, + 'c':927 + } +) + +func( + [ + 'a', + 'b', + 'c', + ] +) + +func( + [ + 'a', + 'b', + 'c', + ], +) + +func( # a + [ # b + "c", # c + "d", # d + "e", # e + ] # f +) # g + +func( # a + { # b + "c": 1, # c + "d": 2, # d + "e": 3, # e + } # f +) # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func( + [ # preserve me but hug brackets + "c", + "d", + "e", + ] +) + +func( + [ + # preserve me but hug brackets + "c", + "d", + "e", + ] +) + +func( + [ + "c", + # preserve me but hug brackets + "d", + "e", + ] +) + +func( + [ + "c", + "d", + "e", + # preserve me but hug brackets + ] +) + +func( + [ + "c", + "d", + "e", + ] # preserve me but hug brackets +) + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func([x for x in "long line long line long line long line long line long line long line"]) +func([x for x in [x for x in "long line long line long line long line long line long line long line"]]) + +func({"short line"}) +func({"long line", "long long line", "long long long line", "long long long long line", "long long long long long line"}) +func({{"long line", "long long line", "long long long line", "long long long long line", "long long long long long line"}}) +func(("long line", "long long line", "long long long line", "long long long long line", "long long long long long line")) +func((("long line", "long long line", "long long long line", "long long long long line", "long long long long long line"))) +func([["long line", "long long line", "long long long line", "long long long long line", "long long long long long line"]]) + +# Do not hug if the argument fits on a single line. +func({"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"}) +func(("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line")) +func(["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"]) +func(**{"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit---"}) +func(*("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit----")) +array = [{"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"}] +array = [("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line")] +array = [["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"]] + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +nested_mapping = {"key": [{"a very long key 1": "with a very long value", "a very long key 2": "with a very long value"}]} +nested_array = [[["long line", "long long line", "long long long line", "long long long long line", "long long long long long line"]]] +explicit_exploding = [[["short", "line",],],] +single_item_do_not_explode = Context({ + "version": get_docs_version(), +}) + +foo(*["long long long long long line", "long long long long long line", "long long long long long line"]) + +foo(*[str(i) for i in range(100000000000000000000000000000000000000000000000000000000000)]) + +foo( + **{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": 1, + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb": 2, + "ccccccccccccccccccccccccccccccccc": 3, + **other, + } +) + +foo(**{x: y for x, y in enumerate(["long long long long line","long long long long line"])}) + +# Edge case when deciding whether to hug the brackets without inner content. +very_very_very_long_variable = very_very_very_long_module.VeryVeryVeryVeryLongClassName([[]]) + +for foo in ["a", "b"]: + output.extend([ + individual + for + # Foobar + container in xs_by_y[foo] + # Foobar + for individual in container["nested"] + ]) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -47,17 +47,21 @@ + ], + ) + +-func([ # a # b +- "c", # c +- "d", # d +- "e", # e +-]) # f # g ++func( # a ++ [ # b ++ "c", # c ++ "d", # d ++ "e", # e ++ ] # f ++) # g + +-func({ # a # b +- "c": 1, # c +- "d": 2, # d +- "e": 3, # e +-}) # f # g ++func( # a ++ { # b ++ "c": 1, # c ++ "d": 2, # d ++ "e": 3, # e ++ } # f ++) # g + + func( + # preserve me +@@ -95,11 +99,13 @@ + # preserve me but hug brackets + ]) + +-func([ +- "c", +- "d", +- "e", +-]) # preserve me but hug brackets ++func( ++ [ ++ "c", ++ "d", ++ "e", ++ ] # preserve me but hug brackets ++) + + func( + [ +@@ -111,10 +117,10 @@ + ) + + func([x for x in "short line"]) +-func( +- [x for x in "long line long line long line long line long line long line long line"] +-) + func([ ++ x for x in "long line long line long line long line long line long line long line" ++]) ++func([ + x + for x in [ + x +@@ -130,13 +136,15 @@ + "long long long long line", + "long long long long long line", + }) +-func({{ +- "long line", +- "long long line", +- "long long long line", +- "long long long long line", +- "long long long long long line", +-}}) ++func({ ++ { ++ "long line", ++ "long long line", ++ "long long long line", ++ "long long long long line", ++ "long long long long long line", ++ } ++}) + func(( + "long line", + "long long line", +@@ -151,30 +159,62 @@ + "long long long long line", + "long long long long long line", + ))) +-func([[ +- "long line", +- "long long line", +- "long long long line", +- "long long long long line", +- "long long long long long line", +-]]) ++func([ ++ [ ++ "long line", ++ "long long line", ++ "long long long line", ++ "long long long long line", ++ "long long long long long line", ++ ] ++]) + + # Do not hug if the argument fits on a single line. +-func( +- {"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"} +-) +-func( +- ("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line") +-) +-func( +- ["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"] +-) +-func( +- **{"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit---"} +-) +-func( +- *("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit----") +-) ++func({ ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++}) ++func(( ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++)) ++func([ ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++]) ++func(**{ ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit---", ++}) ++func(*( ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit line", ++ "fit----", ++)) + array = [ + {"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"} + ] +@@ -194,18 +234,24 @@ + ) + + nested_mapping = { +- "key": [{ +- "a very long key 1": "with a very long value", +- "a very long key 2": "with a very long value", +- }] ++ "key": [ ++ { ++ "a very long key 1": "with a very long value", ++ "a very long key 2": "with a very long value", ++ } ++ ] + } +-nested_array = [[[ +- "long line", +- "long long line", +- "long long long line", +- "long long long long line", +- "long long long long long line", +-]]] ++nested_array = [ ++ [ ++ [ ++ "long line", ++ "long long line", ++ "long long long line", ++ "long long long long line", ++ "long long long long long line", ++ ] ++ ] ++] + explicit_exploding = [ + [ + [ +@@ -240,9 +286,9 @@ + }) + + # Edge case when deciding whether to hug the brackets without inner content. +-very_very_very_long_variable = very_very_very_long_module.VeryVeryVeryVeryLongClassName( +- [[]] +-) ++very_very_very_long_variable = very_very_very_long_module.VeryVeryVeryVeryLongClassName([ ++ [] ++]) + + for foo in ["a", "b"]: + output.extend([ +``` + +## Ruff Output + +```python +def foo_brackets(request): + return JsonResponse({ + "var_1": foo, + "var_2": bar, + }) + + +def foo_square_brackets(request): + return JsonResponse([ + "var_1", + "var_2", + ]) + + +func({ + "a": 37, + "b": 42, + "c": 927, + "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111, +}) + +func([ + "random_string_number_one", + "random_string_number_two", + "random_string_number_three", + "random_string_number_four", +]) + +func({ + # expand me + "a": 37, + "b": 42, + "c": 927, +}) + +func([ + "a", + "b", + "c", +]) + +func( + [ + "a", + "b", + "c", + ], +) + +func( # a + [ # b + "c", # c + "d", # d + "e", # e + ] # f +) # g + +func( # a + { # b + "c": 1, # c + "d": 2, # d + "e": 3, # e + } # f +) # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func([ # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + "c", + # preserve me but hug brackets + "d", + "e", +]) + +func([ + "c", + "d", + "e", + # preserve me but hug brackets +]) + +func( + [ + "c", + "d", + "e", + ] # preserve me but hug brackets +) + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func([ + x for x in "long line long line long line long line long line long line long line" +]) +func([ + x + for x in [ + x + for x in "long line long line long line long line long line long line long line" + ] +]) + +func({"short line"}) +func({ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +}) +func({ + { + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", + } +}) +func(( + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +)) +func((( + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +))) +func([ + [ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", + ] +]) + +# Do not hug if the argument fits on a single line. +func({ + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", +}) +func(( + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", +)) +func([ + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", +]) +func(**{ + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit---", +}) +func(*( + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit line", + "fit----", +)) +array = [ + {"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"} +] +array = [ + ("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line") +] +array = [ + ["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"] +] + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +nested_mapping = { + "key": [ + { + "a very long key 1": "with a very long value", + "a very long key 2": "with a very long value", + } + ] +} +nested_array = [ + [ + [ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", + ] + ] +] +explicit_exploding = [ + [ + [ + "short", + "line", + ], + ], +] +single_item_do_not_explode = Context({ + "version": get_docs_version(), +}) + +foo(*[ + "long long long long long line", + "long long long long long line", + "long long long long long line", +]) + +foo(*[ + str(i) for i in range(100000000000000000000000000000000000000000000000000000000000) +]) + +foo(**{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": 1, + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb": 2, + "ccccccccccccccccccccccccccccccccc": 3, + **other, +}) + +foo(**{ + x: y for x, y in enumerate(["long long long long line", "long long long long line"]) +}) + +# Edge case when deciding whether to hug the brackets without inner content. +very_very_very_long_variable = very_very_very_long_module.VeryVeryVeryVeryLongClassName([ + [] +]) + +for foo in ["a", "b"]: + output.extend([ + individual + for + # Foobar + container in xs_by_y[foo] + # Foobar + for individual in container["nested"] + ]) +``` + +## Black Output + +```python +def foo_brackets(request): + return JsonResponse({ + "var_1": foo, + "var_2": bar, + }) + + +def foo_square_brackets(request): + return JsonResponse([ + "var_1", + "var_2", + ]) + + +func({ + "a": 37, + "b": 42, + "c": 927, + "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111, +}) + +func([ + "random_string_number_one", + "random_string_number_two", + "random_string_number_three", + "random_string_number_four", +]) + +func({ + # expand me + "a": 37, + "b": 42, + "c": 927, +}) + +func([ + "a", + "b", + "c", +]) + +func( + [ + "a", + "b", + "c", + ], +) + +func([ # a # b + "c", # c + "d", # d + "e", # e +]) # f # g + +func({ # a # b + "c": 1, # c + "d": 2, # d + "e": 3, # e +}) # f # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func([ # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + "c", + # preserve me but hug brackets + "d", + "e", +]) + +func([ + "c", + "d", + "e", + # preserve me but hug brackets +]) + +func([ + "c", + "d", + "e", +]) # preserve me but hug brackets + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func( + [x for x in "long line long line long line long line long line long line long line"] +) +func([ + x + for x in [ + x + for x in "long line long line long line long line long line long line long line" + ] +]) + +func({"short line"}) +func({ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +}) +func({{ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +}}) +func(( + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +)) +func((( + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +))) +func([[ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +]]) + +# Do not hug if the argument fits on a single line. +func( + {"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"} +) +func( + ("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line") +) +func( + ["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"] +) +func( + **{"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit---"} +) +func( + *("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit----") +) +array = [ + {"fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"} +] +array = [ + ("fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line") +] +array = [ + ["fit line", "fit line", "fit line", "fit line", "fit line", "fit line", "fit line"] +] + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +nested_mapping = { + "key": [{ + "a very long key 1": "with a very long value", + "a very long key 2": "with a very long value", + }] +} +nested_array = [[[ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +]]] +explicit_exploding = [ + [ + [ + "short", + "line", + ], + ], +] +single_item_do_not_explode = Context({ + "version": get_docs_version(), +}) + +foo(*[ + "long long long long long line", + "long long long long long line", + "long long long long long line", +]) + +foo(*[ + str(i) for i in range(100000000000000000000000000000000000000000000000000000000000) +]) + +foo(**{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": 1, + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb": 2, + "ccccccccccccccccccccccccccccccccc": 3, + **other, +}) + +foo(**{ + x: y for x, y in enumerate(["long long long long line", "long long long long line"]) +}) + +# Edge case when deciding whether to hug the brackets without inner content. +very_very_very_long_variable = very_very_very_long_module.VeryVeryVeryVeryLongClassName( + [[]] +) + +for foo in ["a", "b"]: + output.extend([ + individual + for + # Foobar + container in xs_by_y[foo] + # Foobar + for individual in container["nested"] + ]) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_dict_values.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_dict_values.py.snap new file mode 100644 index 0000000000000..d60d394b858fb --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_dict_values.py.snap @@ -0,0 +1,201 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_dict_values.py +--- +## Input + +```python +my_dict = { + "something_something": + r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t", +} + +my_dict = { + "a key in my dict": a_very_long_variable * and_a_very_long_function_call() / 100000.0 +} + +my_dict = { + "a key in my dict": a_very_long_variable * and_a_very_long_function_call() * and_another_long_func() / 100000.0 +} + +my_dict = { + "a key in my dict": MyClass.some_attribute.first_call().second_call().third_call(some_args="some value") +} + +{ + 'xxxxxx': + xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx( + xxxxxxxxxxxxxx={ + 'x': + xxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + .xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + .xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx={ + 'x': x.xx, + 'x': x.x, + })))) + }), +} +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,32 +1,26 @@ + my_dict = { +- "something_something": ( +- r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" +- r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" +- r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" +- ), ++ "something_something": r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" ++ r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" ++ r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t", + } + + my_dict = { +- "a key in my dict": ( +- a_very_long_variable * and_a_very_long_function_call() / 100000.0 +- ) ++ "a key in my dict": a_very_long_variable ++ * and_a_very_long_function_call() ++ / 100000.0 + } + + my_dict = { +- "a key in my dict": ( +- a_very_long_variable +- * and_a_very_long_function_call() +- * and_another_long_func() +- / 100000.0 +- ) ++ "a key in my dict": a_very_long_variable ++ * and_a_very_long_function_call() ++ * and_another_long_func() ++ / 100000.0 + } + + my_dict = { +- "a key in my dict": ( +- MyClass.some_attribute.first_call() +- .second_call() +- .third_call(some_args="some value") +- ) ++ "a key in my dict": MyClass.some_attribute.first_call() ++ .second_call() ++ .third_call(some_args="some value") + } + + { +``` + +## Ruff Output + +```python +my_dict = { + "something_something": r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t", +} + +my_dict = { + "a key in my dict": a_very_long_variable + * and_a_very_long_function_call() + / 100000.0 +} + +my_dict = { + "a key in my dict": a_very_long_variable + * and_a_very_long_function_call() + * and_another_long_func() + / 100000.0 +} + +my_dict = { + "a key in my dict": MyClass.some_attribute.first_call() + .second_call() + .third_call(some_args="some value") +} + +{ + "xxxxxx": xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx( + xxxxxxxxxxxxxx={ + "x": xxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx={ + "x": x.xx, + "x": x.x, + } + ) + ) + ) + ) + } + ), +} +``` + +## Black Output + +```python +my_dict = { + "something_something": ( + r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + ), +} + +my_dict = { + "a key in my dict": ( + a_very_long_variable * and_a_very_long_function_call() / 100000.0 + ) +} + +my_dict = { + "a key in my dict": ( + a_very_long_variable + * and_a_very_long_function_call() + * and_another_long_func() + / 100000.0 + ) +} + +my_dict = { + "a key in my dict": ( + MyClass.some_attribute.first_call() + .second_call() + .third_call(some_args="some value") + ) +} + +{ + "xxxxxx": xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx( + xxxxxxxxxxxxxx={ + "x": xxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx={ + "x": x.xx, + "x": x.x, + } + ) + ) + ) + ) + } + ), +} +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings.py.snap new file mode 100644 index 0000000000000..a589aeffed92e --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings.py.snap @@ -0,0 +1,2036 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings.py +--- +## Input + +```python +x = "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +x += "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +y = ( + 'Short string' +) + +print('This is a really long string inside of a print statement with extra arguments attached at the end of it.', x, y, z) + +print("This is a really long string inside of a print statement with no extra arguments attached at the end of it.") + +D1 = {"The First": "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", "The Second": "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary."} + +D2 = {1.0: "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", 2.0: "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary."} + +D3 = {x: "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", y: "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary."} + +D4 = {"A long and ridiculous {}".format(string_key): "This is a really really really long string that has to go i,side of a dictionary. It is soooo bad.", some_func("calling", "some", "stuff"): "This is a really really really long string that has to go inside of a dictionary. It is {soooo} bad (#{x}).".format(sooo="soooo", x=2), "A %s %s" % ("formatted", "string"): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)." % ("soooo", 2)} + +D5 = { # Test for https://github.com/psf/black/issues/3261 + ("This is a really long string that can't be expected to fit in one line and is used as a nested dict's key"): {"inner": "value"}, +} + +D6 = { # Test for https://github.com/psf/black/issues/3261 + ("This is a really long string that can't be expected to fit in one line and is used as a dict's key"): ["value1", "value2"], +} + +L1 = ["The is a short string", "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a list literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", short_call("arg", {"key": "value"}), "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a list literal.", ("parens should be stripped for short string in list")] + +L2 = ["This is a really long string that can't be expected to fit in one line and is the only child of a list literal."] + +S1 = {"The is a short string", "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a set literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", short_call("arg", {"key": "value"}), "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a set literal.", ("parens should be stripped for short string in set")} + +S2 = {"This is a really long string that can't be expected to fit in one line and is the only child of a set literal."} + +T1 = ("The is a short string", "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a tuple literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", short_call("arg", {"key": "value"}), "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a tuple literal.", ("parens should be stripped for short string in list")) + +T2 = ("This is a really long string that can't be expected to fit in one line and is the only child of a tuple literal.",) + +func_with_keywords(my_arg, my_kwarg="Long keyword strings also need to be wrapped, but they will probably need to be handled a little bit differently.") + +bad_split1 = ( + 'But what should happen when code has already been formatted but in the wrong way? Like' + " with a space at the end instead of the beginning. Or what about when it is split too soon?" +) + +bad_split2 = "But what should happen when code has already " \ + "been formatted but in the wrong way? Like " \ + "with a space at the end instead of the " \ + "beginning. Or what about when it is split too " \ + "soon? In the case of a split that is too " \ + "short, black will try to honer the custom " \ + "split." + +bad_split3 = ( + "What if we have inline comments on " # First Comment + "each line of a bad split? In that " # Second Comment + "case, we should just leave it alone." # Third Comment +) + +bad_split_func1( + "But what should happen when code has already " + "been formatted but in the wrong way? Like " + "with a space at the end instead of the " + "beginning. Or what about when it is split too " + "soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split.", + xxx, yyy, zzz +) + +bad_split_func2( + xxx, yyy, zzz, + long_string_kwarg="But what should happen when code has already been formatted but in the wrong way? Like " + "with a space at the end instead of the beginning. Or what about when it is split too " + "soon?", +) + +bad_split_func3( + ( + "But what should happen when code has already " + r"been formatted but in the wrong way? Like " + "with a space at the end instead of the " + r"beginning. Or what about when it is split too " + r"soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split." + ), + xxx, + yyy, + zzz, +) + +inline_comments_func1( + "if there are inline " + "comments in the middle " + # Here is the standard alone comment. + "of the implicitly concatenated " + "string, we should handle " + "them correctly", + xxx, +) + +inline_comments_func2( + "what if the string is very very very very very very very very very very long and this part does " + "not fit into a single line? " + # Here is the standard alone comment. + "then the string should still be properly handled by merging and splitting " + "it into parts that fit in line length.", + xxx, +) + +raw_string = r"This is a long raw string. When re-formatting this string, black needs to make sure it prepends the 'r' onto the new string." + +fmt_string1 = "We also need to be sure to preserve any and all {} which may or may not be attached to the string in question.".format("method calls") + +fmt_string2 = "But what about when the string is {} but {}".format("short", "the method call is really really really really really really really really long?") + +old_fmt_string1 = "While we are on the topic of %s, we should also note that old-style formatting must also be preserved, since some %s still uses it." % ("formatting", "code") + +old_fmt_string2 = "This is a %s %s %s %s" % ("really really really really really", "old", "way to format strings!", "Use f-strings instead!") + +old_fmt_string3 = "Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s" % ("really really really really really", "old", "way to format strings!", "Use f-strings instead!") + +fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one." + +fstring_with_no_fexprs = f"Some regular string that needs to get split certainly but is NOT an fstring by any means whatsoever." + +comment_string = "Long lines with inline comments should have their comments appended to the reformatted string's enclosing right parentheses." # This comment gets thrown to the top. + +arg_comment_string = print("Long lines with inline comments which are apart of (and not the only member of) an argument list should have their comments appended to the reformatted string's enclosing left parentheses.", # This comment gets thrown to the top. + "Arg #2", "Arg #3", "Arg #4", "Arg #5") + +pragma_comment_string1 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa: E501 + +pragma_comment_string2 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa + +"""This is a really really really long triple quote string and it should not be touched.""" + +triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched.""" + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception." + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string {}.".format("formatting") + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s." % "formatting" + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s." % ("string", "formatting") + +some_function_call("With a reallly generic name and with a really really long string that is, at some point down the line, " + added + " to a variable and then added to another string.") + +some_function_call("With a reallly generic name and with a really really long string that is, at some point down the line, " + added + " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.", "and a second argument", and_a_third) + +return "A really really really really really really really really really really really really really long {} {}".format("return", "value") + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma which should NOT be there.", +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma which should NOT be there.", # comment after comma +) + +func_with_bad_comma( + ( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there." + ), +) + +func_with_bad_comma( + ( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there." + ), # comment after comma +) + +func_with_bad_parens_that_wont_fit_in_one_line( + ("short string that should have parens stripped"), + x, + y, + z +) + +func_with_bad_parens_that_wont_fit_in_one_line( + x, + y, + ("short string that should have parens stripped"), + z +) + +func_with_bad_parens( + ("short string that should have parens stripped"), + x, + y, + z, +) + +func_with_bad_parens( + x, + y, + ("short string that should have parens stripped"), + z, +) + +annotated_variable: Final = "This is a large " + STRING + " that has been " + CONCATENATED + "using the '+' operator." +annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." +annotated_variable: Literal["fakse_literal"] = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." + +backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\" +backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\\\" +backslashes = "This is a really 'long' string with \"embedded double quotes\" and 'single' quotes that also handles checking for an odd number of backslashes \\\", like this...\\\\\\" + +short_string = ( + "Hi" + " there." +) + +func_call( + short_string=( + "Hi" + " there." + ) +) + +raw_strings = r"Don't" " get" r" merged" " unless they are all raw." + +def foo(): + yield "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +x = f"This is a {{really}} long string that needs to be split without a doubt (i.e. most definitely). In short, this {string} that can't possibly be {{expected}} to fit all together on one line. In {fact} it may even take up three or more lines... like four or five... but probably just four." + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # type: ignore + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # noqa + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # pylint: disable=some-pylint-check + " of it." +) + +string_with_nameescape = ( + "........................................................................ \N{LAO KO LA}" +) + +string_with_nameescape = ( + "........................................................................... \N{LAO KO LA}" +) + +string_with_nameescape = ( + "............................................................................ \N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + "...................................................................... \\\N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + "......................................................................... \\\N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + ".......................................................................... \\\N{LAO KO LA}" +) + +string_with_escaped_nameescape = ( + "........................................................................ \\N{LAO KO LA}" +) + +string_with_escaped_nameescape = ( + "........................................................................... \\N{LAO KO LA}" +) + +msg = lambda x: f"this is a very very very long lambda value {x} that doesn't fit on a single line" + +dict_with_lambda_values = { + "join": lambda j: ( + f"{j.__class__.__name__}({some_function_call(j.left)}, " + f"{some_function_call(j.right)})" + ), +} + +# Complex string concatenations with a method call in the middle. +code = ( + (" return [\n") + + ( + ", \n".join( + " (%r, self.%s, visitor.%s)" + % (attrname, attrname, visit_name) + for attrname, visit_name in names + ) + ) + + ("\n ]\n") +) + + +# Test case of an outer string' parens enclose an inner string's parens. +call(body=("%s %s" % ((",".join(items)), suffix))) + +log.info(f'Skipping: {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]=} {desc["exposure_max"]=}') + +log.info(f"Skipping: {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']=} {desc['exposure_max']=}") + +log.info(f'Skipping: {desc["db_id"]} {foo("bar",x=123)} {"foo" != "bar"} {(x := "abc=")} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {"a" == "b" == "c" == "d"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}') + +log.info(f'Skipping: { longer_longer_longer_longer_longer_longer_name [ "db_id" ] [ "another_key" ] = : .3f }') + +log.info(f'''Skipping: {"a" == 'b'} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}''') + +log.info(f'''Skipping: {'a' == "b"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}''') + +log.info(f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}""") +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,175 +1,108 @@ +-x = ( +- "This is a really long string that can't possibly be expected to fit all together" +- " on one line. In fact it may even take up three or more lines... like four or" +- " five... but probably just three." +-) ++x = "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +-x += ( +- "This is a really long string that can't possibly be expected to fit all together" +- " on one line. In fact it may even take up three or more lines... like four or" +- " five... but probably just three." +-) ++x += "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + + y = "Short string" + + print( +- "This is a really long string inside of a print statement with extra arguments" +- " attached at the end of it.", ++ "This is a really long string inside of a print statement with extra arguments attached at the end of it.", + x, + y, + z, + ) + + print( +- "This is a really long string inside of a print statement with no extra arguments" +- " attached at the end of it." ++ "This is a really long string inside of a print statement with no extra arguments attached at the end of it." + ) + + D1 = { +- "The First": ( +- "This is a really long string that can't possibly be expected to fit all" +- " together on one line. Also it is inside a dictionary, so formatting is more" +- " difficult." +- ), +- "The Second": ( +- "This is another really really (not really) long string that also can't be" +- " expected to fit on one line and is, like the other string, inside a" +- " dictionary." +- ), ++ "The First": "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", ++ "The Second": "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary.", + } + + D2 = { +- 1.0: ( +- "This is a really long string that can't possibly be expected to fit all" +- " together on one line. Also it is inside a dictionary, so formatting is more" +- " difficult." +- ), +- 2.0: ( +- "This is another really really (not really) long string that also can't be" +- " expected to fit on one line and is, like the other string, inside a" +- " dictionary." +- ), ++ 1.0: "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", ++ 2.0: "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary.", + } + + D3 = { +- x: ( +- "This is a really long string that can't possibly be expected to fit all" +- " together on one line. Also it is inside a dictionary, so formatting is more" +- " difficult." +- ), +- y: ( +- "This is another really really (not really) long string that also can't be" +- " expected to fit on one line and is, like the other string, inside a" +- " dictionary." +- ), ++ x: "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", ++ y: "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary.", + } + + D4 = { +- "A long and ridiculous {}".format(string_key): ( +- "This is a really really really long string that has to go i,side of a" +- " dictionary. It is soooo bad." +- ), +- some_func("calling", "some", "stuff"): ( +- "This is a really really really long string that has to go inside of a" +- " dictionary. It is {soooo} bad (#{x}).".format(sooo="soooo", x=2) ++ "A long and ridiculous {}".format( ++ string_key ++ ): "This is a really really really long string that has to go i,side of a dictionary. It is soooo bad.", ++ some_func( ++ "calling", "some", "stuff" ++ ): "This is a really really really long string that has to go inside of a dictionary. It is {soooo} bad (#{x}).".format( ++ sooo="soooo", x=2 + ), + "A %s %s" +- % ("formatted", "string"): ( +- "This is a really really really long string that has to go inside of a" +- " dictionary. It is %s bad (#%d)." % ("soooo", 2) +- ), ++ % ( ++ "formatted", ++ "string", ++ ): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)." ++ % ("soooo", 2), + } + + D5 = { # Test for https://github.com/psf/black/issues/3261 +- "This is a really long string that can't be expected to fit in one line and is used as a nested dict's key": { +- "inner": "value" +- }, ++ ( ++ "This is a really long string that can't be expected to fit in one line and is used as a nested dict's key" ++ ): {"inner": "value"}, + } + + D6 = { # Test for https://github.com/psf/black/issues/3261 +- "This is a really long string that can't be expected to fit in one line and is used as a dict's key": [ +- "value1", +- "value2", +- ], ++ ( ++ "This is a really long string that can't be expected to fit in one line and is used as a dict's key" ++ ): ["value1", "value2"], + } + + L1 = [ + "The is a short string", +- ( +- "This is a really long string that can't possibly be expected to fit all" +- " together on one line. Also it is inside a list literal, so it's expected to" +- " be wrapped in parens when splitting to avoid implicit str concatenation." +- ), ++ "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a list literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", + short_call("arg", {"key": "value"}), +- ( +- "This is another really really (not really) long string that also can't be" +- " expected to fit on one line and is, like the other string, inside a list" +- " literal." +- ), +- "parens should be stripped for short string in list", ++ "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a list literal.", ++ ("parens should be stripped for short string in list"), + ] + + L2 = [ +- "This is a really long string that can't be expected to fit in one line and is the" +- " only child of a list literal." ++ "This is a really long string that can't be expected to fit in one line and is the only child of a list literal." + ] + + S1 = { + "The is a short string", +- ( +- "This is a really long string that can't possibly be expected to fit all" +- " together on one line. Also it is inside a set literal, so it's expected to be" +- " wrapped in parens when splitting to avoid implicit str concatenation." +- ), ++ "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a set literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", + short_call("arg", {"key": "value"}), +- ( +- "This is another really really (not really) long string that also can't be" +- " expected to fit on one line and is, like the other string, inside a set" +- " literal." +- ), +- "parens should be stripped for short string in set", ++ "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a set literal.", ++ ("parens should be stripped for short string in set"), + } + + S2 = { +- "This is a really long string that can't be expected to fit in one line and is the" +- " only child of a set literal." ++ "This is a really long string that can't be expected to fit in one line and is the only child of a set literal." + } + + T1 = ( + "The is a short string", +- ( +- "This is a really long string that can't possibly be expected to fit all" +- " together on one line. Also it is inside a tuple literal, so it's expected to" +- " be wrapped in parens when splitting to avoid implicit str concatenation." +- ), ++ "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a tuple literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", + short_call("arg", {"key": "value"}), +- ( +- "This is another really really (not really) long string that also can't be" +- " expected to fit on one line and is, like the other string, inside a tuple" +- " literal." +- ), +- "parens should be stripped for short string in list", ++ "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a tuple literal.", ++ ("parens should be stripped for short string in list"), + ) + + T2 = ( +- ( +- "This is a really long string that can't be expected to fit in one line and is" +- " the only child of a tuple literal." +- ), ++ "This is a really long string that can't be expected to fit in one line and is the only child of a tuple literal.", + ) + + func_with_keywords( + my_arg, +- my_kwarg=( +- "Long keyword strings also need to be wrapped, but they will probably need to" +- " be handled a little bit differently." +- ), ++ my_kwarg="Long keyword strings also need to be wrapped, but they will probably need to be handled a little bit differently.", + ) + + bad_split1 = ( +- "But what should happen when code has already been formatted but in the wrong way?" +- " Like with a space at the end instead of the beginning. Or what about when it is" +- " split too soon?" ++ "But what should happen when code has already been formatted but in the wrong way? Like" ++ " with a space at the end instead of the beginning. Or what about when it is split too soon?" + ) + + bad_split2 = ( +@@ -205,11 +138,9 @@ + xxx, + yyy, + zzz, +- long_string_kwarg=( +- "But what should happen when code has already been formatted but in the wrong" +- " way? Like with a space at the end instead of the beginning. Or what about" +- " when it is split too soon?" +- ), ++ long_string_kwarg="But what should happen when code has already been formatted but in the wrong way? Like " ++ "with a space at the end instead of the beginning. Or what about when it is split too " ++ "soon?", + ) + + bad_split_func3( +@@ -228,29 +159,28 @@ + ) + + inline_comments_func1( +- "if there are inline comments in the middle " ++ "if there are inline " ++ "comments in the middle " + # Here is the standard alone comment. +- "of the implicitly concatenated string, we should handle them correctly", ++ "of the implicitly concatenated " ++ "string, we should handle " ++ "them correctly", + xxx, + ) + + inline_comments_func2( +- "what if the string is very very very very very very very very very very long and" +- " this part does not fit into a single line? " ++ "what if the string is very very very very very very very very very very long and this part does " ++ "not fit into a single line? " + # Here is the standard alone comment. + "then the string should still be properly handled by merging and splitting " + "it into parts that fit in line length.", + xxx, + ) + +-raw_string = ( +- r"This is a long raw string. When re-formatting this string, black needs to make" +- r" sure it prepends the 'r' onto the new string." +-) ++raw_string = r"This is a long raw string. When re-formatting this string, black needs to make sure it prepends the 'r' onto the new string." + +-fmt_string1 = ( +- "We also need to be sure to preserve any and all {} which may or may not be" +- " attached to the string in question.".format("method calls") ++fmt_string1 = "We also need to be sure to preserve any and all {} which may or may not be attached to the string in question.".format( ++ "method calls" + ) + + fmt_string2 = "But what about when the string is {} but {}".format( +@@ -259,8 +189,8 @@ + ) + + old_fmt_string1 = ( +- "While we are on the topic of %s, we should also note that old-style formatting" +- " must also be preserved, since some %s still uses it." % ("formatting", "code") ++ "While we are on the topic of %s, we should also note that old-style formatting must also be preserved, since some %s still uses it." ++ % ("formatting", "code") + ) + + old_fmt_string2 = "This is a %s %s %s %s" % ( +@@ -271,8 +201,7 @@ + ) + + old_fmt_string3 = ( +- "Whereas only the strings after the percent sign were long in the last example," +- " this example uses a long initial string as well. This is another %s %s %s %s" ++ "Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s" + % ( + "really really really really really", + "old", +@@ -281,26 +210,14 @@ + ) + ) + +-fstring = ( +- f"f-strings definitely make things more {difficult} than they need to be for" +- " {black}. But boy they sure are handy. The problem is that some lines will need" +- f" to have the 'f' whereas others do not. This {line}, for example, needs one." +-) ++fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one." + +-fstring_with_no_fexprs = ( +- f"Some regular string that needs to get split certainly but is NOT an fstring by" +- f" any means whatsoever." +-) ++fstring_with_no_fexprs = f"Some regular string that needs to get split certainly but is NOT an fstring by any means whatsoever." + +-comment_string = ( # This comment gets thrown to the top. +- "Long lines with inline comments should have their comments appended to the" +- " reformatted string's enclosing right parentheses." +-) ++comment_string = "Long lines with inline comments should have their comments appended to the reformatted string's enclosing right parentheses." # This comment gets thrown to the top. + + arg_comment_string = print( +- "Long lines with inline comments which are apart of (and not the only member of) an" +- " argument list should have their comments appended to the reformatted string's" +- " enclosing left parentheses.", # This comment gets thrown to the top. ++ "Long lines with inline comments which are apart of (and not the only member of) an argument list should have their comments appended to the reformatted string's enclosing left parentheses.", # This comment gets thrown to the top. + "Arg #2", + "Arg #3", + "Arg #4", +@@ -315,80 +232,72 @@ + + triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched.""" + +-assert some_type_of_boolean_expression, ( +- "Followed by a really really really long string that is used to provide context to" +- " the AssertionError exception." +-) ++assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception." + +-assert some_type_of_boolean_expression, ( +- "Followed by a really really really long string that is used to provide context to" +- " the AssertionError exception, which uses dynamic string {}.".format("formatting") ++assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string {}.".format( ++ "formatting" + ) + + assert some_type_of_boolean_expression, ( +- "Followed by a really really really long string that is used to provide context to" +- " the AssertionError exception, which uses dynamic string %s." % "formatting" ++ "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s." ++ % "formatting" + ) + + assert some_type_of_boolean_expression, ( +- "Followed by a really really really long string that is used to provide context to" +- " the AssertionError exception, which uses dynamic %s %s." ++ "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s." + % ("string", "formatting") + ) + + some_function_call( +- "With a reallly generic name and with a really really long string that is, at some" +- " point down the line, " ++ "With a reallly generic name and with a really really long string that is, at some point down the line, " + + added + + " to a variable and then added to another string." + ) + + some_function_call( +- "With a reallly generic name and with a really really long string that is, at some" +- " point down the line, " ++ "With a reallly generic name and with a really really long string that is, at some point down the line, " + + added +- + " to a variable and then added to another string. But then what happens when the" +- " final string is also supppppperrrrr long?! Well then that second (realllllllly" +- " long) string should be split too.", ++ + " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.", + "and a second argument", + and_a_third, + ) + +-return ( +- "A really really really really really really really really really really really" +- " really really long {} {}".format("return", "value") ++return "A really really really really really really really really really really really really really long {} {}".format( ++ "return", "value" + ) + + func_with_bad_comma( +- "This is a really long string argument to a function that has a trailing comma" +- " which should NOT be there.", ++ "This is a really long string argument to a function that has a trailing comma which should NOT be there.", + ) + + func_with_bad_comma( +- "This is a really long string argument to a function that has a trailing comma" +- " which should NOT be there.", # comment after comma ++ "This is a really long string argument to a function that has a trailing comma which should NOT be there.", # comment after comma + ) + + func_with_bad_comma( +- "This is a really long string argument to a function that has a trailing comma" +- " which should NOT be there.", ++ ( ++ "This is a really long string argument to a function that has a trailing comma" ++ " which should NOT be there." ++ ), + ) + + func_with_bad_comma( +- "This is a really long string argument to a function that has a trailing comma" +- " which should NOT be there.", # comment after comma ++ ( ++ "This is a really long string argument to a function that has a trailing comma" ++ " which should NOT be there." ++ ), # comment after comma + ) + + func_with_bad_parens_that_wont_fit_in_one_line( +- "short string that should have parens stripped", x, y, z ++ ("short string that should have parens stripped"), x, y, z + ) + + func_with_bad_parens_that_wont_fit_in_one_line( +- x, y, "short string that should have parens stripped", z ++ x, y, ("short string that should have parens stripped"), z + ) + + func_with_bad_parens( +- "short string that should have parens stripped", ++ ("short string that should have parens stripped"), + x, + y, + z, +@@ -397,7 +306,7 @@ + func_with_bad_parens( + x, + y, +- "short string that should have parens stripped", ++ ("short string that should have parens stripped"), + z, + ) + +@@ -408,50 +317,27 @@ + + CONCATENATED + + "using the '+' operator." + ) +-annotated_variable: Final = ( +- "This is a large string that has a type annotation attached to it. A type" +- " annotation should NOT stop a long string from being wrapped." +-) ++annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." + annotated_variable: Literal["fakse_literal"] = ( +- "This is a large string that has a type annotation attached to it. A type" +- " annotation should NOT stop a long string from being wrapped." ++ "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." + ) + +-backslashes = ( +- "This is a really long string with \"embedded\" double quotes and 'single' quotes" +- " that also handles checking for an even number of backslashes \\" +-) +-backslashes = ( +- "This is a really long string with \"embedded\" double quotes and 'single' quotes" +- " that also handles checking for an even number of backslashes \\\\" +-) +-backslashes = ( +- "This is a really 'long' string with \"embedded double quotes\" and 'single' quotes" +- ' that also handles checking for an odd number of backslashes \\", like' +- " this...\\\\\\" +-) ++backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\" ++backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\\\" ++backslashes = "This is a really 'long' string with \"embedded double quotes\" and 'single' quotes that also handles checking for an odd number of backslashes \\\", like this...\\\\\\" + +-short_string = "Hi there." ++short_string = "Hi" " there." + +-func_call(short_string="Hi there.") ++func_call(short_string=("Hi" " there.")) + + raw_strings = r"Don't" " get" r" merged" " unless they are all raw." + + + def foo(): +- yield ( +- "This is a really long string that can't possibly be expected to fit all" +- " together on one line. In fact it may even take up three or more lines... like" +- " four or five... but probably just three." +- ) ++ yield "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + + +-x = ( +- "This is a {really} long string that needs to be split without a doubt (i.e." +- f" most definitely). In short, this {string} that can't possibly be {{expected}} to" +- f" fit all together on one line. In {fact} it may even take up three or more" +- " lines... like four or five... but probably just four." +-) ++x = f"This is a {{really}} long string that needs to be split without a doubt (i.e. most definitely). In short, this {string} that can't possibly be {{expected}} to fit all together on one line. In {fact} it may even take up three or more lines... like four or five... but probably just four." + + long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # type: ignore +@@ -468,51 +354,24 @@ + " of it." + ) + +-string_with_nameescape = ( +- "........................................................................" +- " \N{LAO KO LA}" +-) ++string_with_nameescape = "........................................................................ \N{LAO KO LA}" + +-string_with_nameescape = ( +- "..........................................................................." +- " \N{LAO KO LA}" +-) ++string_with_nameescape = "........................................................................... \N{LAO KO LA}" + +-string_with_nameescape = ( +- "............................................................................" +- " \N{LAO KO LA}" +-) ++string_with_nameescape = "............................................................................ \N{LAO KO LA}" + +-string_with_nameescape_and_escaped_backslash = ( +- "......................................................................" +- " \\\N{LAO KO LA}" +-) ++string_with_nameescape_and_escaped_backslash = "...................................................................... \\\N{LAO KO LA}" + +-string_with_nameescape_and_escaped_backslash = ( +- "........................................................................." +- " \\\N{LAO KO LA}" +-) ++string_with_nameescape_and_escaped_backslash = "......................................................................... \\\N{LAO KO LA}" + +-string_with_nameescape_and_escaped_backslash = ( +- ".........................................................................." +- " \\\N{LAO KO LA}" +-) ++string_with_nameescape_and_escaped_backslash = ".......................................................................... \\\N{LAO KO LA}" + +-string_with_escaped_nameescape = ( +- "........................................................................ \\N{LAO" +- " KO LA}" +-) ++string_with_escaped_nameescape = "........................................................................ \\N{LAO KO LA}" + +-string_with_escaped_nameescape = ( +- "..........................................................................." +- " \\N{LAO KO LA}" +-) ++string_with_escaped_nameescape = "........................................................................... \\N{LAO KO LA}" + + msg = ( +- lambda x: ( +- f"this is a very very very long lambda value {x} that doesn't fit on a single" +- " line" +- ) ++ lambda x: f"this is a very very very long lambda value {x} that doesn't fit on a single line" + ) + + dict_with_lambda_values = { +@@ -524,61 +383,54 @@ + + # Complex string concatenations with a method call in the middle. + code = ( +- " return [\n" +- + ", \n".join( +- " (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name) +- for attrname, visit_name in names ++ (" return [\n") ++ + ( ++ ", \n".join( ++ " (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name) ++ for attrname, visit_name in names ++ ) + ) +- + "\n ]\n" ++ + ("\n ]\n") + ) + + + # Test case of an outer string' parens enclose an inner string's parens. +-call(body="%s %s" % (",".join(items), suffix)) ++call(body=("%s %s" % ((",".join(items)), suffix))) + + log.info( +- "Skipping:" +- f' {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]=} {desc["exposure_max"]=}' ++ f'Skipping: {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]=} {desc["exposure_max"]=}' + ) + + log.info( +- "Skipping:" +- f" {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']=} {desc['exposure_max']=}" ++ f"Skipping: {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']=} {desc['exposure_max']=}" + ) + + log.info( +- "Skipping:" +- f" {desc['db_id']} {foo('bar',x=123)} {'foo' != 'bar'} {(x := 'abc=')} {pos_share=} {desc['status']} {desc['exposure_max']}" ++ f'Skipping: {desc["db_id"]} {foo("bar",x=123)} {"foo" != "bar"} {(x := "abc=")} {pos_share=} {desc["status"]} {desc["exposure_max"]}' + ) + + log.info( +- "Skipping:" +- f' {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' ++ f'Skipping: {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' + ) + + log.info( +- "Skipping:" +- f' {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' ++ f'Skipping: {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' + ) + + log.info( +- "Skipping:" +- f' {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' ++ f'Skipping: {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' + ) + + log.info( +- "Skipping:" +- f" {'a' == 'b' == 'c' == 'd'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}" ++ f'Skipping: {"a" == "b" == "c" == "d"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' + ) + + log.info( +- "Skipping:" +- f' {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' ++ f'Skipping: {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' + ) + + log.info( +- "Skipping:" +- f' { longer_longer_longer_longer_longer_longer_name [ "db_id" ] [ "another_key" ] = : .3f }' ++ f'Skipping: { longer_longer_longer_longer_longer_longer_name [ "db_id" ] [ "another_key" ] = : .3f }' + ) + + log.info( +``` + +## Ruff Output + +```python +x = "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +x += "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + +y = "Short string" + +print( + "This is a really long string inside of a print statement with extra arguments attached at the end of it.", + x, + y, + z, +) + +print( + "This is a really long string inside of a print statement with no extra arguments attached at the end of it." +) + +D1 = { + "The First": "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", + "The Second": "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary.", +} + +D2 = { + 1.0: "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", + 2.0: "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary.", +} + +D3 = { + x: "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a dictionary, so formatting is more difficult.", + y: "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a dictionary.", +} + +D4 = { + "A long and ridiculous {}".format( + string_key + ): "This is a really really really long string that has to go i,side of a dictionary. It is soooo bad.", + some_func( + "calling", "some", "stuff" + ): "This is a really really really long string that has to go inside of a dictionary. It is {soooo} bad (#{x}).".format( + sooo="soooo", x=2 + ), + "A %s %s" + % ( + "formatted", + "string", + ): "This is a really really really long string that has to go inside of a dictionary. It is %s bad (#%d)." + % ("soooo", 2), +} + +D5 = { # Test for https://github.com/psf/black/issues/3261 + ( + "This is a really long string that can't be expected to fit in one line and is used as a nested dict's key" + ): {"inner": "value"}, +} + +D6 = { # Test for https://github.com/psf/black/issues/3261 + ( + "This is a really long string that can't be expected to fit in one line and is used as a dict's key" + ): ["value1", "value2"], +} + +L1 = [ + "The is a short string", + "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a list literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", + short_call("arg", {"key": "value"}), + "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a list literal.", + ("parens should be stripped for short string in list"), +] + +L2 = [ + "This is a really long string that can't be expected to fit in one line and is the only child of a list literal." +] + +S1 = { + "The is a short string", + "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a set literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", + short_call("arg", {"key": "value"}), + "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a set literal.", + ("parens should be stripped for short string in set"), +} + +S2 = { + "This is a really long string that can't be expected to fit in one line and is the only child of a set literal." +} + +T1 = ( + "The is a short string", + "This is a really long string that can't possibly be expected to fit all together on one line. Also it is inside a tuple literal, so it's expected to be wrapped in parens when splitting to avoid implicit str concatenation.", + short_call("arg", {"key": "value"}), + "This is another really really (not really) long string that also can't be expected to fit on one line and is, like the other string, inside a tuple literal.", + ("parens should be stripped for short string in list"), +) + +T2 = ( + "This is a really long string that can't be expected to fit in one line and is the only child of a tuple literal.", +) + +func_with_keywords( + my_arg, + my_kwarg="Long keyword strings also need to be wrapped, but they will probably need to be handled a little bit differently.", +) + +bad_split1 = ( + "But what should happen when code has already been formatted but in the wrong way? Like" + " with a space at the end instead of the beginning. Or what about when it is split too soon?" +) + +bad_split2 = ( + "But what should happen when code has already " + "been formatted but in the wrong way? Like " + "with a space at the end instead of the " + "beginning. Or what about when it is split too " + "soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split." +) + +bad_split3 = ( + "What if we have inline comments on " # First Comment + "each line of a bad split? In that " # Second Comment + "case, we should just leave it alone." # Third Comment +) + +bad_split_func1( + "But what should happen when code has already " + "been formatted but in the wrong way? Like " + "with a space at the end instead of the " + "beginning. Or what about when it is split too " + "soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split.", + xxx, + yyy, + zzz, +) + +bad_split_func2( + xxx, + yyy, + zzz, + long_string_kwarg="But what should happen when code has already been formatted but in the wrong way? Like " + "with a space at the end instead of the beginning. Or what about when it is split too " + "soon?", +) + +bad_split_func3( + ( + "But what should happen when code has already " + r"been formatted but in the wrong way? Like " + "with a space at the end instead of the " + r"beginning. Or what about when it is split too " + r"soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split." + ), + xxx, + yyy, + zzz, +) + +inline_comments_func1( + "if there are inline " + "comments in the middle " + # Here is the standard alone comment. + "of the implicitly concatenated " + "string, we should handle " + "them correctly", + xxx, +) + +inline_comments_func2( + "what if the string is very very very very very very very very very very long and this part does " + "not fit into a single line? " + # Here is the standard alone comment. + "then the string should still be properly handled by merging and splitting " + "it into parts that fit in line length.", + xxx, +) + +raw_string = r"This is a long raw string. When re-formatting this string, black needs to make sure it prepends the 'r' onto the new string." + +fmt_string1 = "We also need to be sure to preserve any and all {} which may or may not be attached to the string in question.".format( + "method calls" +) + +fmt_string2 = "But what about when the string is {} but {}".format( + "short", + "the method call is really really really really really really really really long?", +) + +old_fmt_string1 = ( + "While we are on the topic of %s, we should also note that old-style formatting must also be preserved, since some %s still uses it." + % ("formatting", "code") +) + +old_fmt_string2 = "This is a %s %s %s %s" % ( + "really really really really really", + "old", + "way to format strings!", + "Use f-strings instead!", +) + +old_fmt_string3 = ( + "Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s" + % ( + "really really really really really", + "old", + "way to format strings!", + "Use f-strings instead!", + ) +) + +fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one." + +fstring_with_no_fexprs = f"Some regular string that needs to get split certainly but is NOT an fstring by any means whatsoever." + +comment_string = "Long lines with inline comments should have their comments appended to the reformatted string's enclosing right parentheses." # This comment gets thrown to the top. + +arg_comment_string = print( + "Long lines with inline comments which are apart of (and not the only member of) an argument list should have their comments appended to the reformatted string's enclosing left parentheses.", # This comment gets thrown to the top. + "Arg #2", + "Arg #3", + "Arg #4", + "Arg #5", +) + +pragma_comment_string1 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa: E501 + +pragma_comment_string2 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa + +"""This is a really really really long triple quote string and it should not be touched.""" + +triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched.""" + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception." + +assert some_type_of_boolean_expression, "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string {}.".format( + "formatting" +) + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic string %s." + % "formatting" +) + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to the AssertionError exception, which uses dynamic %s %s." + % ("string", "formatting") +) + +some_function_call( + "With a reallly generic name and with a really really long string that is, at some point down the line, " + + added + + " to a variable and then added to another string." +) + +some_function_call( + "With a reallly generic name and with a really really long string that is, at some point down the line, " + + added + + " to a variable and then added to another string. But then what happens when the final string is also supppppperrrrr long?! Well then that second (realllllllly long) string should be split too.", + "and a second argument", + and_a_third, +) + +return "A really really really really really really really really really really really really really long {} {}".format( + "return", "value" +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma which should NOT be there.", +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma which should NOT be there.", # comment after comma +) + +func_with_bad_comma( + ( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there." + ), +) + +func_with_bad_comma( + ( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there." + ), # comment after comma +) + +func_with_bad_parens_that_wont_fit_in_one_line( + ("short string that should have parens stripped"), x, y, z +) + +func_with_bad_parens_that_wont_fit_in_one_line( + x, y, ("short string that should have parens stripped"), z +) + +func_with_bad_parens( + ("short string that should have parens stripped"), + x, + y, + z, +) + +func_with_bad_parens( + x, + y, + ("short string that should have parens stripped"), + z, +) + +annotated_variable: Final = ( + "This is a large " + + STRING + + " that has been " + + CONCATENATED + + "using the '+' operator." +) +annotated_variable: Final = "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." +annotated_variable: Literal["fakse_literal"] = ( + "This is a large string that has a type annotation attached to it. A type annotation should NOT stop a long string from being wrapped." +) + +backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\" +backslashes = "This is a really long string with \"embedded\" double quotes and 'single' quotes that also handles checking for an even number of backslashes \\\\" +backslashes = "This is a really 'long' string with \"embedded double quotes\" and 'single' quotes that also handles checking for an odd number of backslashes \\\", like this...\\\\\\" + +short_string = "Hi" " there." + +func_call(short_string=("Hi" " there.")) + +raw_strings = r"Don't" " get" r" merged" " unless they are all raw." + + +def foo(): + yield "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." + + +x = f"This is a {{really}} long string that needs to be split without a doubt (i.e. most definitely). In short, this {string} that can't possibly be {{expected}} to fit all together on one line. In {fact} it may even take up three or more lines... like four or five... but probably just four." + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # type: ignore + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # noqa + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # pylint: disable=some-pylint-check + " of it." +) + +string_with_nameescape = "........................................................................ \N{LAO KO LA}" + +string_with_nameescape = "........................................................................... \N{LAO KO LA}" + +string_with_nameescape = "............................................................................ \N{LAO KO LA}" + +string_with_nameescape_and_escaped_backslash = "...................................................................... \\\N{LAO KO LA}" + +string_with_nameescape_and_escaped_backslash = "......................................................................... \\\N{LAO KO LA}" + +string_with_nameescape_and_escaped_backslash = ".......................................................................... \\\N{LAO KO LA}" + +string_with_escaped_nameescape = "........................................................................ \\N{LAO KO LA}" + +string_with_escaped_nameescape = "........................................................................... \\N{LAO KO LA}" + +msg = ( + lambda x: f"this is a very very very long lambda value {x} that doesn't fit on a single line" +) + +dict_with_lambda_values = { + "join": lambda j: ( + f"{j.__class__.__name__}({some_function_call(j.left)}, " + f"{some_function_call(j.right)})" + ), +} + +# Complex string concatenations with a method call in the middle. +code = ( + (" return [\n") + + ( + ", \n".join( + " (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name) + for attrname, visit_name in names + ) + ) + + ("\n ]\n") +) + + +# Test case of an outer string' parens enclose an inner string's parens. +call(body=("%s %s" % ((",".join(items)), suffix))) + +log.info( + f'Skipping: {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]=} {desc["exposure_max"]=}' +) + +log.info( + f"Skipping: {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']=} {desc['exposure_max']=}" +) + +log.info( + f'Skipping: {desc["db_id"]} {foo("bar",x=123)} {"foo" != "bar"} {(x := "abc=")} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + f'Skipping: {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + f'Skipping: {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + f'Skipping: {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + f'Skipping: {"a" == "b" == "c" == "d"} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + f'Skipping: {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + f'Skipping: { longer_longer_longer_longer_longer_longer_name [ "db_id" ] [ "another_key" ] = : .3f }' +) + +log.info( + f"""Skipping: {"a" == 'b'} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}""" +) + +log.info( + f"""Skipping: {'a' == "b"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}""" +) + +log.info( + f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}""" +) +``` + +## Black Output + +```python +x = ( + "This is a really long string that can't possibly be expected to fit all together" + " on one line. In fact it may even take up three or more lines... like four or" + " five... but probably just three." +) + +x += ( + "This is a really long string that can't possibly be expected to fit all together" + " on one line. In fact it may even take up three or more lines... like four or" + " five... but probably just three." +) + +y = "Short string" + +print( + "This is a really long string inside of a print statement with extra arguments" + " attached at the end of it.", + x, + y, + z, +) + +print( + "This is a really long string inside of a print statement with no extra arguments" + " attached at the end of it." +) + +D1 = { + "The First": ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a dictionary, so formatting is more" + " difficult." + ), + "The Second": ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a" + " dictionary." + ), +} + +D2 = { + 1.0: ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a dictionary, so formatting is more" + " difficult." + ), + 2.0: ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a" + " dictionary." + ), +} + +D3 = { + x: ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a dictionary, so formatting is more" + " difficult." + ), + y: ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a" + " dictionary." + ), +} + +D4 = { + "A long and ridiculous {}".format(string_key): ( + "This is a really really really long string that has to go i,side of a" + " dictionary. It is soooo bad." + ), + some_func("calling", "some", "stuff"): ( + "This is a really really really long string that has to go inside of a" + " dictionary. It is {soooo} bad (#{x}).".format(sooo="soooo", x=2) + ), + "A %s %s" + % ("formatted", "string"): ( + "This is a really really really long string that has to go inside of a" + " dictionary. It is %s bad (#%d)." % ("soooo", 2) + ), +} + +D5 = { # Test for https://github.com/psf/black/issues/3261 + "This is a really long string that can't be expected to fit in one line and is used as a nested dict's key": { + "inner": "value" + }, +} + +D6 = { # Test for https://github.com/psf/black/issues/3261 + "This is a really long string that can't be expected to fit in one line and is used as a dict's key": [ + "value1", + "value2", + ], +} + +L1 = [ + "The is a short string", + ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a list literal, so it's expected to" + " be wrapped in parens when splitting to avoid implicit str concatenation." + ), + short_call("arg", {"key": "value"}), + ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a list" + " literal." + ), + "parens should be stripped for short string in list", +] + +L2 = [ + "This is a really long string that can't be expected to fit in one line and is the" + " only child of a list literal." +] + +S1 = { + "The is a short string", + ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a set literal, so it's expected to be" + " wrapped in parens when splitting to avoid implicit str concatenation." + ), + short_call("arg", {"key": "value"}), + ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a set" + " literal." + ), + "parens should be stripped for short string in set", +} + +S2 = { + "This is a really long string that can't be expected to fit in one line and is the" + " only child of a set literal." +} + +T1 = ( + "The is a short string", + ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. Also it is inside a tuple literal, so it's expected to" + " be wrapped in parens when splitting to avoid implicit str concatenation." + ), + short_call("arg", {"key": "value"}), + ( + "This is another really really (not really) long string that also can't be" + " expected to fit on one line and is, like the other string, inside a tuple" + " literal." + ), + "parens should be stripped for short string in list", +) + +T2 = ( + ( + "This is a really long string that can't be expected to fit in one line and is" + " the only child of a tuple literal." + ), +) + +func_with_keywords( + my_arg, + my_kwarg=( + "Long keyword strings also need to be wrapped, but they will probably need to" + " be handled a little bit differently." + ), +) + +bad_split1 = ( + "But what should happen when code has already been formatted but in the wrong way?" + " Like with a space at the end instead of the beginning. Or what about when it is" + " split too soon?" +) + +bad_split2 = ( + "But what should happen when code has already " + "been formatted but in the wrong way? Like " + "with a space at the end instead of the " + "beginning. Or what about when it is split too " + "soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split." +) + +bad_split3 = ( + "What if we have inline comments on " # First Comment + "each line of a bad split? In that " # Second Comment + "case, we should just leave it alone." # Third Comment +) + +bad_split_func1( + "But what should happen when code has already " + "been formatted but in the wrong way? Like " + "with a space at the end instead of the " + "beginning. Or what about when it is split too " + "soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split.", + xxx, + yyy, + zzz, +) + +bad_split_func2( + xxx, + yyy, + zzz, + long_string_kwarg=( + "But what should happen when code has already been formatted but in the wrong" + " way? Like with a space at the end instead of the beginning. Or what about" + " when it is split too soon?" + ), +) + +bad_split_func3( + ( + "But what should happen when code has already " + r"been formatted but in the wrong way? Like " + "with a space at the end instead of the " + r"beginning. Or what about when it is split too " + r"soon? In the case of a split that is too " + "short, black will try to honer the custom " + "split." + ), + xxx, + yyy, + zzz, +) + +inline_comments_func1( + "if there are inline comments in the middle " + # Here is the standard alone comment. + "of the implicitly concatenated string, we should handle them correctly", + xxx, +) + +inline_comments_func2( + "what if the string is very very very very very very very very very very long and" + " this part does not fit into a single line? " + # Here is the standard alone comment. + "then the string should still be properly handled by merging and splitting " + "it into parts that fit in line length.", + xxx, +) + +raw_string = ( + r"This is a long raw string. When re-formatting this string, black needs to make" + r" sure it prepends the 'r' onto the new string." +) + +fmt_string1 = ( + "We also need to be sure to preserve any and all {} which may or may not be" + " attached to the string in question.".format("method calls") +) + +fmt_string2 = "But what about when the string is {} but {}".format( + "short", + "the method call is really really really really really really really really long?", +) + +old_fmt_string1 = ( + "While we are on the topic of %s, we should also note that old-style formatting" + " must also be preserved, since some %s still uses it." % ("formatting", "code") +) + +old_fmt_string2 = "This is a %s %s %s %s" % ( + "really really really really really", + "old", + "way to format strings!", + "Use f-strings instead!", +) + +old_fmt_string3 = ( + "Whereas only the strings after the percent sign were long in the last example," + " this example uses a long initial string as well. This is another %s %s %s %s" + % ( + "really really really really really", + "old", + "way to format strings!", + "Use f-strings instead!", + ) +) + +fstring = ( + f"f-strings definitely make things more {difficult} than they need to be for" + " {black}. But boy they sure are handy. The problem is that some lines will need" + f" to have the 'f' whereas others do not. This {line}, for example, needs one." +) + +fstring_with_no_fexprs = ( + f"Some regular string that needs to get split certainly but is NOT an fstring by" + f" any means whatsoever." +) + +comment_string = ( # This comment gets thrown to the top. + "Long lines with inline comments should have their comments appended to the" + " reformatted string's enclosing right parentheses." +) + +arg_comment_string = print( + "Long lines with inline comments which are apart of (and not the only member of) an" + " argument list should have their comments appended to the reformatted string's" + " enclosing left parentheses.", # This comment gets thrown to the top. + "Arg #2", + "Arg #3", + "Arg #4", + "Arg #5", +) + +pragma_comment_string1 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa: E501 + +pragma_comment_string2 = "Lines which end with an inline pragma comment of the form `# : <...>` should be left alone." # noqa + +"""This is a really really really long triple quote string and it should not be touched.""" + +triple_quote_string = """This is a really really really long triple quote string assignment and it should not be touched.""" + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to" + " the AssertionError exception." +) + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to" + " the AssertionError exception, which uses dynamic string {}.".format("formatting") +) + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to" + " the AssertionError exception, which uses dynamic string %s." % "formatting" +) + +assert some_type_of_boolean_expression, ( + "Followed by a really really really long string that is used to provide context to" + " the AssertionError exception, which uses dynamic %s %s." + % ("string", "formatting") +) + +some_function_call( + "With a reallly generic name and with a really really long string that is, at some" + " point down the line, " + + added + + " to a variable and then added to another string." +) + +some_function_call( + "With a reallly generic name and with a really really long string that is, at some" + " point down the line, " + + added + + " to a variable and then added to another string. But then what happens when the" + " final string is also supppppperrrrr long?! Well then that second (realllllllly" + " long) string should be split too.", + "and a second argument", + and_a_third, +) + +return ( + "A really really really really really really really really really really really" + " really really long {} {}".format("return", "value") +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there.", +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there.", # comment after comma +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there.", +) + +func_with_bad_comma( + "This is a really long string argument to a function that has a trailing comma" + " which should NOT be there.", # comment after comma +) + +func_with_bad_parens_that_wont_fit_in_one_line( + "short string that should have parens stripped", x, y, z +) + +func_with_bad_parens_that_wont_fit_in_one_line( + x, y, "short string that should have parens stripped", z +) + +func_with_bad_parens( + "short string that should have parens stripped", + x, + y, + z, +) + +func_with_bad_parens( + x, + y, + "short string that should have parens stripped", + z, +) + +annotated_variable: Final = ( + "This is a large " + + STRING + + " that has been " + + CONCATENATED + + "using the '+' operator." +) +annotated_variable: Final = ( + "This is a large string that has a type annotation attached to it. A type" + " annotation should NOT stop a long string from being wrapped." +) +annotated_variable: Literal["fakse_literal"] = ( + "This is a large string that has a type annotation attached to it. A type" + " annotation should NOT stop a long string from being wrapped." +) + +backslashes = ( + "This is a really long string with \"embedded\" double quotes and 'single' quotes" + " that also handles checking for an even number of backslashes \\" +) +backslashes = ( + "This is a really long string with \"embedded\" double quotes and 'single' quotes" + " that also handles checking for an even number of backslashes \\\\" +) +backslashes = ( + "This is a really 'long' string with \"embedded double quotes\" and 'single' quotes" + ' that also handles checking for an odd number of backslashes \\", like' + " this...\\\\\\" +) + +short_string = "Hi there." + +func_call(short_string="Hi there.") + +raw_strings = r"Don't" " get" r" merged" " unless they are all raw." + + +def foo(): + yield ( + "This is a really long string that can't possibly be expected to fit all" + " together on one line. In fact it may even take up three or more lines... like" + " four or five... but probably just three." + ) + + +x = ( + "This is a {really} long string that needs to be split without a doubt (i.e." + f" most definitely). In short, this {string} that can't possibly be {{expected}} to" + f" fit all together on one line. In {fact} it may even take up three or more" + " lines... like four or five... but probably just four." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # type: ignore + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # noqa + " of it." +) + +long_unmergable_string_with_pragma = ( + "This is a really long string that can't be merged because it has a likely pragma at the end" # pylint: disable=some-pylint-check + " of it." +) + +string_with_nameescape = ( + "........................................................................" + " \N{LAO KO LA}" +) + +string_with_nameescape = ( + "..........................................................................." + " \N{LAO KO LA}" +) + +string_with_nameescape = ( + "............................................................................" + " \N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + "......................................................................" + " \\\N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + "........................................................................." + " \\\N{LAO KO LA}" +) + +string_with_nameescape_and_escaped_backslash = ( + ".........................................................................." + " \\\N{LAO KO LA}" +) + +string_with_escaped_nameescape = ( + "........................................................................ \\N{LAO" + " KO LA}" +) + +string_with_escaped_nameescape = ( + "..........................................................................." + " \\N{LAO KO LA}" +) + +msg = ( + lambda x: ( + f"this is a very very very long lambda value {x} that doesn't fit on a single" + " line" + ) +) + +dict_with_lambda_values = { + "join": lambda j: ( + f"{j.__class__.__name__}({some_function_call(j.left)}, " + f"{some_function_call(j.right)})" + ), +} + +# Complex string concatenations with a method call in the middle. +code = ( + " return [\n" + + ", \n".join( + " (%r, self.%s, visitor.%s)" % (attrname, attrname, visit_name) + for attrname, visit_name in names + ) + + "\n ]\n" +) + + +# Test case of an outer string' parens enclose an inner string's parens. +call(body="%s %s" % (",".join(items), suffix)) + +log.info( + "Skipping:" + f' {desc["db_id"]=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]=} {desc["exposure_max"]=}' +) + +log.info( + "Skipping:" + f" {desc['db_id']=} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']=} {desc['exposure_max']=}" +) + +log.info( + "Skipping:" + f" {desc['db_id']} {foo('bar',x=123)} {'foo' != 'bar'} {(x := 'abc=')} {pos_share=} {desc['status']} {desc['exposure_max']}" +) + +log.info( + "Skipping:" + f' {desc["db_id"]} {desc["ms_name"]} {money=} {(x := "abc=")=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + "Skipping:" + f' {desc["db_id"]} {foo("bar",x=123)=} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + "Skipping:" + f' {foo("asdf")=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + "Skipping:" + f" {'a' == 'b' == 'c' == 'd'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}" +) + +log.info( + "Skipping:" + f' {"a" == "b" == "c" == "d"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}' +) + +log.info( + "Skipping:" + f' { longer_longer_longer_longer_longer_longer_name [ "db_id" ] [ "another_key" ] = : .3f }' +) + +log.info( + f"""Skipping: {"a" == 'b'} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}""" +) + +log.info( + f"""Skipping: {'a' == "b"=} {desc["ms_name"]} {money=} {dte=} {pos_share=} {desc["status"]} {desc["exposure_max"]}""" +) + +log.info( + f"""Skipping: {'a' == 'b'} {desc['ms_name']} {money=} {dte=} {pos_share=} {desc['status']} {desc['exposure_max']}""" +) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__east_asian_width.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__east_asian_width.py.snap new file mode 100644 index 0000000000000..7ba67786746f8 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__east_asian_width.py.snap @@ -0,0 +1,75 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__east_asian_width.py +--- +## Input + +```python +# The following strings do not have not-so-many chars, but are long enough +# when these are rendered in a monospace font (if the renderer respects +# Unicode East Asian Width properties). +hangul = '코드포인트 수는 적으나 실제 터미널이나 에디터에서 렌더링될 땐 너무 길어서 줄바꿈이 필요한 문자열' +hanzi = '中文測試:代碼點數量少,但在真正的終端模擬器或編輯器中呈現時太長,因此需要換行的字符串。' +japanese = 'コードポイントの数は少ないが、実際の端末エミュレータやエディタでレンダリングされる時は長すぎる為、改行が要る文字列' +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,16 +1,6 @@ + # The following strings do not have not-so-many chars, but are long enough + # when these are rendered in a monospace font (if the renderer respects + # Unicode East Asian Width properties). +-hangul = ( +- "코드포인트 수는 적으나 실제 터미널이나 에디터에서 렌더링될 땐 너무 길어서 줄바꿈이" +- " 필요한 문자열" +-) +-hanzi = ( +- "中文測試:代碼點數量少,但在真正的終端模擬器或編輯器中呈現時太長," +- "因此需要換行的字符串。" +-) +-japanese = ( +- "コードポイントの数は少ないが、" +- "実際の端末エミュレータやエディタでレンダリングされる時は長すぎる為、" +- "改行が要る文字列" +-) ++hangul = "코드포인트 수는 적으나 실제 터미널이나 에디터에서 렌더링될 땐 너무 길어서 줄바꿈이 필요한 문자열" ++hanzi = "中文測試:代碼點數量少,但在真正的終端模擬器或編輯器中呈現時太長,因此需要換行的字符串。" ++japanese = "コードポイントの数は少ないが、実際の端末エミュレータやエディタでレンダリングされる時は長すぎる為、改行が要る文字列" +``` + +## Ruff Output + +```python +# The following strings do not have not-so-many chars, but are long enough +# when these are rendered in a monospace font (if the renderer respects +# Unicode East Asian Width properties). +hangul = "코드포인트 수는 적으나 실제 터미널이나 에디터에서 렌더링될 땐 너무 길어서 줄바꿈이 필요한 문자열" +hanzi = "中文測試:代碼點數量少,但在真正的終端模擬器或編輯器中呈現時太長,因此需要換行的字符串。" +japanese = "コードポイントの数は少ないが、実際の端末エミュレータやエディタでレンダリングされる時は長すぎる為、改行が要る文字列" +``` + +## Black Output + +```python +# The following strings do not have not-so-many chars, but are long enough +# when these are rendered in a monospace font (if the renderer respects +# Unicode East Asian Width properties). +hangul = ( + "코드포인트 수는 적으나 실제 터미널이나 에디터에서 렌더링될 땐 너무 길어서 줄바꿈이" + " 필요한 문자열" +) +hanzi = ( + "中文測試:代碼點數量少,但在真正的終端模擬器或編輯器中呈現時太長," + "因此需要換行的字符串。" +) +japanese = ( + "コードポイントの数は少ないが、" + "実際の端末エミュレータやエディタでレンダリングされる時は長すぎる為、" + "改行が要る文字列" +) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__edge_case.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__edge_case.py.snap new file mode 100644 index 0000000000000..4db3fa039c2a8 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__edge_case.py.snap @@ -0,0 +1,340 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__edge_case.py +--- +## Input + +```python +some_variable = "This string is long but not so long that it needs to be split just yet" +some_variable = 'This string is long but not so long that it needs to be split just yet' +some_variable = "This string is long, just long enough that it needs to be split, u get?" +some_variable = 'This string is long, just long enough that it needs to be split, u get?' +some_variable = "This string is long, just long enough that it needs to be split, u get? So we stay" +some_variable = 'This string is long, just long enough that it needs to be split, u get? So we stay' +some_variable = "This string is long, just long enough that it needs to be split, u get? So we split" +some_variable = 'This string is long, just long enough that it needs to be split, u get? So we split' +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at alll".format("ha") +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at allll".format("ha") +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at alllllllllll".format("ha") +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at allllllllllll".format("ha") +some_variable = "This is a long string that will end with a method that is not calleddd".format +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take place.............", + xyz, + "Some really long string that needs to get split eventually but I'm running out of things to say" + some_string_inside_a_variable +) +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take place.............." +) +return "Hi there. This is areally really reallllly long string that needs to be split!!!" +ternary_expression = ( + "Short String" + if some_condition + else "This is a really long string that will eventually need to be split right here." +) +return f'{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaa' +return f'{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaaa' +assert str(result) == "This long string should be split at some point right close to or around hereeeeeee" +assert str(result) < "This long string should be split at some point right close to or around hereeeeee" +assert "A format string: %s" % "This long string should be split at some point right close to or around hereeeeeee" != result +msg += "This long string should be wrapped in parens at some point right around hereeeee" +msg += "This long string should be split at some point right close to or around hereeeeeeee" +msg += "This long string should not be split at any point ever since it is just righttt" +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -12,51 +12,33 @@ + some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we stay" + ) +-some_variable = ( +- "This string is long, just long enough that it needs to be split, u get? So we" +- " split" +-) +-some_variable = ( +- "This string is long, just long enough that it needs to be split, u get? So we" +- " split" +-) +-some_variable = ( +- "This string is long but not so long that it needs hahahah toooooo be so greatttt" +- " {} that I just can't think of any more good words to say about it at alll".format( +- "ha" +- ) ++some_variable = "This string is long, just long enough that it needs to be split, u get? So we split" ++some_variable = "This string is long, just long enough that it needs to be split, u get? So we split" ++some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at alll".format( ++ "ha" + ) +-some_variable = ( +- "This string is long but not so long that it needs hahahah toooooo be so greatttt" +- " {} that I just can't think of any more good words to say about it at allll" +- .format("ha") ++some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at allll".format( ++ "ha" + ) +-some_variable = ( +- "This string is long but not so long that it needs hahahah toooooo be so greatttt" +- " {} that I just can't think of any more good words to say about it at alllllllllll" +- .format("ha") ++some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at alllllllllll".format( ++ "ha" + ) +-some_variable = ( +- "This string is long but not so long that it needs hahahah toooooo be so greatttt" +- " {} that I just can't think of any more good words to say about it at" +- " allllllllllll".format("ha") ++some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at allllllllllll".format( ++ "ha" + ) + some_variable = ( + "This is a long string that will end with a method that is not calleddd".format + ) + addition_inside_tuple = ( + some_string_inside_a_variable +- + "Some string that is just long enough to cause a split to take" +- " place.............", ++ + "Some string that is just long enough to cause a split to take place.............", + xyz, +- "Some really long string that needs to get split eventually but I'm running out of" +- " things to say" ++ "Some really long string that needs to get split eventually but I'm running out of things to say" + + some_string_inside_a_variable, + ) + addition_inside_tuple = ( + some_string_inside_a_variable +- + "Some string that is just long enough to cause a split to take" +- " place.............." ++ + "Some string that is just long enough to cause a split to take place.............." + ) + return ( + "Hi there. This is areally really reallllly long string that needs to be split!!!" +@@ -64,9 +46,7 @@ + ternary_expression = ( + "Short String" + if some_condition +- else ( +- "This is a really long string that will eventually need to be split right here." +- ) ++ else "This is a really long string that will eventually need to be split right here." + ) + return ( + f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaa" +@@ -74,25 +54,19 @@ + return f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaaa" + assert ( + str(result) +- == "This long string should be split at some point right close to or around" +- " hereeeeeee" ++ == "This long string should be split at some point right close to or around hereeeeeee" + ) + assert ( + str(result) +- < "This long string should be split at some point right close to or around" +- " hereeeeee" ++ < "This long string should be split at some point right close to or around hereeeeee" + ) + assert ( + "A format string: %s" +- % "This long string should be split at some point right close to or around" +- " hereeeeeee" ++ % "This long string should be split at some point right close to or around hereeeeeee" + != result + ) + msg += ( + "This long string should be wrapped in parens at some point right around hereeeee" + ) +-msg += ( +- "This long string should be split at some point right close to or around" +- " hereeeeeeee" +-) ++msg += "This long string should be split at some point right close to or around hereeeeeeee" + msg += "This long string should not be split at any point ever since it is just righttt" +``` + +## Ruff Output + +```python +some_variable = "This string is long but not so long that it needs to be split just yet" +some_variable = "This string is long but not so long that it needs to be split just yet" +some_variable = ( + "This string is long, just long enough that it needs to be split, u get?" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get?" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we stay" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we stay" +) +some_variable = "This string is long, just long enough that it needs to be split, u get? So we split" +some_variable = "This string is long, just long enough that it needs to be split, u get? So we split" +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at alll".format( + "ha" +) +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at allll".format( + "ha" +) +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at alllllllllll".format( + "ha" +) +some_variable = "This string is long but not so long that it needs hahahah toooooo be so greatttt {} that I just can't think of any more good words to say about it at allllllllllll".format( + "ha" +) +some_variable = ( + "This is a long string that will end with a method that is not calleddd".format +) +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take place.............", + xyz, + "Some really long string that needs to get split eventually but I'm running out of things to say" + + some_string_inside_a_variable, +) +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take place.............." +) +return ( + "Hi there. This is areally really reallllly long string that needs to be split!!!" +) +ternary_expression = ( + "Short String" + if some_condition + else "This is a really long string that will eventually need to be split right here." +) +return ( + f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaa" +) +return f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaaa" +assert ( + str(result) + == "This long string should be split at some point right close to or around hereeeeeee" +) +assert ( + str(result) + < "This long string should be split at some point right close to or around hereeeeee" +) +assert ( + "A format string: %s" + % "This long string should be split at some point right close to or around hereeeeeee" + != result +) +msg += ( + "This long string should be wrapped in parens at some point right around hereeeee" +) +msg += "This long string should be split at some point right close to or around hereeeeeeee" +msg += "This long string should not be split at any point ever since it is just righttt" +``` + +## Black Output + +```python +some_variable = "This string is long but not so long that it needs to be split just yet" +some_variable = "This string is long but not so long that it needs to be split just yet" +some_variable = ( + "This string is long, just long enough that it needs to be split, u get?" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get?" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we stay" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we stay" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we" + " split" +) +some_variable = ( + "This string is long, just long enough that it needs to be split, u get? So we" + " split" +) +some_variable = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at alll".format( + "ha" + ) +) +some_variable = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at allll" + .format("ha") +) +some_variable = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at alllllllllll" + .format("ha") +) +some_variable = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at" + " allllllllllll".format("ha") +) +some_variable = ( + "This is a long string that will end with a method that is not calleddd".format +) +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take" + " place.............", + xyz, + "Some really long string that needs to get split eventually but I'm running out of" + " things to say" + + some_string_inside_a_variable, +) +addition_inside_tuple = ( + some_string_inside_a_variable + + "Some string that is just long enough to cause a split to take" + " place.............." +) +return ( + "Hi there. This is areally really reallllly long string that needs to be split!!!" +) +ternary_expression = ( + "Short String" + if some_condition + else ( + "This is a really long string that will eventually need to be split right here." + ) +) +return ( + f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaa" +) +return f"{x}/b/c/d/d/d/dadfjsadjsaidoaisjdsfjaofjdfijaidfjaodfjaoifjodjafojdoajaaaaaaaaaaaa" +assert ( + str(result) + == "This long string should be split at some point right close to or around" + " hereeeeeee" +) +assert ( + str(result) + < "This long string should be split at some point right close to or around" + " hereeeeee" +) +assert ( + "A format string: %s" + % "This long string should be split at some point right close to or around" + " hereeeeeee" + != result +) +msg += ( + "This long string should be wrapped in parens at some point right around hereeeee" +) +msg += ( + "This long string should be split at some point right close to or around" + " hereeeeeeee" +) +msg += "This long string should not be split at any point ever since it is just righttt" +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__regression.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__regression.py.snap new file mode 100644 index 0000000000000..762af6aa16c7e --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__regression.py.snap @@ -0,0 +1,2520 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__regression.py +--- +## Input + +```python +class A: + def foo(): + result = type(message)("") + + +# Don't merge multiline (e.g. triple-quoted) strings. +def foo(): + query = ( + """SELECT xxxxxxxxxxxxxxxxxxxx(xxx)""" + """ FROM xxxxxxxxxxxxxxxx WHERE xxxxxxxxxx AND xxx <> xxxxxxxxxxxxxx()""") + +# There was a bug where tuples were being identified as long strings. +long_tuple = ('Apple', 'Berry', 'Cherry', 'Dill', 'Evergreen', 'Fig', + 'Grape', 'Harry', 'Iglu', 'Jaguar') + +stupid_format_method_bug = "Some really long string that just so happens to be the {} {} to force the 'format' method to hang over the line length boundary. This is pretty annoying.".format("perfect", "length") + +class A: + def foo(): + os.system("This is a regression test. xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxxx.".format("xxxxxxxxxx", "xxxxxx", "xxxxxxxxxx")) + + +class A: + def foo(): + XXXXXXXXXXXX.append( + ( + "xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx, xxxx_xxxx_xxxxxxxxxx={})".format( + xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx + ), + my_var, + my_other_var, + ) + ) + +class A: + class B: + def foo(): + bar( + ( + "[{}]: xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx={}" + " xxxx_xxxx_xxxxxxxxxx={}, xxxx={})" + .format(xxxx._xxxxxxxxxxxxxx, xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx, xxxxxxx) + ), + varX, + varY, + varZ, + ) + +def foo(xxxx): + for (xxx_xxxx, _xxx_xxx, _xxx_xxxxx, xxx_xxxx) in xxxx: + for xxx in xxx_xxxx: + assert ("x" in xxx) or ( + xxx in xxx_xxx_xxxxx + ), "{0} xxxxxxx xx {1}, xxx {1} xx xxx xx xxxx xx xxx xxxx: xxx xxxx {2}".format( + xxx_xxxx, xxx, xxxxxx.xxxxxxx(xxx_xxx_xxxxx) + ) + +class A: + def disappearing_comment(): + return ( + ( # xx -x xxxxxxx xx xxx xxxxxxx. + '{{xxx_xxxxxxxxxx_xxxxxxxx}} xxx xxxx' + ' {} {{xxxx}} >&2' + .format( + "{xxxx} {xxxxxx}" + if xxxxx.xx_xxxxxxxxxx + else ( # Disappearing Comment + "--xxxxxxx --xxxxxx=x --xxxxxx-xxxxx=xxxxxx" + " --xxxxxx-xxxx=xxxxxxxxxxx.xxx" + ) + ) + ), + (x, y, z), + ) + +class A: + class B: + def foo(): + xxxxx_xxxx( + xx, "\t" + "@xxxxxx '{xxxx_xxx}\t' > {xxxxxx_xxxx}.xxxxxxx;" + "{xxxx_xxx} >> {xxxxxx_xxxx}.xxxxxxx 2>&1; xx=$$?;" + "xxxx $$xx" + .format(xxxx_xxx=xxxx_xxxxxxx, xxxxxx_xxxx=xxxxxxx + "/" + xxxx_xxx_xxxx, x=xxx_xxxxx_xxxxx_xxx), + x, + y, + z, + ) + +func_call_where_string_arg_has_method_call_and_bad_parens( + ( + "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll.".format("formatting") + ), +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + ( + "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll." % "formatting" + ), +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + ( + "A long string with {}. This {} is so long that it is ridiculous. It can't fit on one line at alllll." % ("formatting", "string") + ), +) + +class A: + def append(self): + if True: + xxxx.xxxxxxx.xxxxx( ('xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx' + % (len(self) + 1, + xxxx.xxxxxxxxxx, + xxxx.xxxxxxxxxx)) + + (' %.3f (%s) to %.3f (%s).\n' + % (xxxx.xxxxxxxxx, + xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx), + x, + xxxx.xxxxxxxxxxxxxx( xx) + ))) + +class A: + def foo(): + some_func_call( + 'xxxxxxxxxx', + ( + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + "\"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; " + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" " + ), + None, + ('xxxxxxxxxxx',), + ), + +class A: + def foo(): + some_func_call( + ( + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; " + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" " + ), + None, + ('xxxxxxxxxxx',), + ), + +xxxxxxx = { 'xx' : 'xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} \ +-xx {1} -xx xxx=xxx_xxxx,xxx_xx,xxx_xxx,xxx_xxxx,xxx_xx,xxx_xxx |\ + xxxxxx -x xxxxxxxx -x xxxxxxxx -x', + 'xx' : 'xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} \ +-xx {1} -xx xxx=xxx_xxxx_xxx_xxxx,xxx_xx_xxx_xxxx,xxx_xxxx_xxx_xxxx,\ +xxx_xx_xxxx_xxxx,xxx_xxx_xxxx,xxx_xxx_xxxx xxxx=xxx | xxxxxx -x xxxxxxxx -x xxxxxxxx -x' +} + +class A: + def foo(self): + if True: + xxxxx_xxxxxxxxxxxx('xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx xxxxxxx ' + + 'xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx'.xxxxxx(xxxxxx_xxxxxx_xxx)) + +class A: + class B: + def foo(): + row = { + 'xxxxxxxxxxxxxxx' : xxxxxx_xxxxx_xxxx, + # 'xxxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxx' + 'xxxxxxxxxx' : xxxxx_xxxxx, + } + +class A: + def xxxx_xxx_xx_xxxxxxxxxx_xxxx_xxxxxxxxx(xxxx): + xxxxxxxx = [ + xxxxxxxxxxxxxxxx( + 'xxxx', + xxxxxxxxxxx={ + 'xxxx' : 1.0, + }, + xxxxxx={'xxxxxx 1' : xxxxxx(xxxx='xxxxxx 1', xxxxxx=600.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + 'xxxxxxx', + xxxxxxxxxxx={ + 'xxxx' : 1.0, + }, + xxxxxx={'xxxxxx 1' : xxxxxx(xxxx='xxxxxx 1', xxxxxx=200.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + 'xxxx', + ), + ] + +some_dictionary = { + 'xxxxx006': ['xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx== xxxxx000 xxxxxxxxxx\n', + 'xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx== xxxxx010 xxxxxxxxxx\n'], + 'xxxxx016': ['xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx== xxxxx000 xxxxxxxxxx\n', + 'xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx== xxxxx010 xxxxxxxxxx\n'] +} + +def foo(): + xxx_xxx = ( + 'xxxx xxx xxxxxxxx_xxxx xx "xxxxxxxxxx".' + '\n xxx: xxxxxx xxxxxxxx_xxxx=xxxxxxxxxx' + ) # xxxx xxxxxxxxxx xxxx xx xxxx xx xxx xxxxxxxx xxxxxx xxxxx. + +some_tuple = ("some string", "some string" " which should be joined") + +some_commented_string = ( # This comment stays at the top. + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at" + " allllllllllll".format("ha") # comments here are fine +) + +some_commented_string = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" # But these + " {} that I just can't think of any more good words to say about it at" # comments will stay + " allllllllllll".format("ha") # comments here are fine +) + +lpar_and_rpar_have_comments = func_call( # LPAR Comment + "Long really ridiculous type of string that shouldn't really even exist at all. I mean commmme onnn!!!", # Comma Comment +) # RPAR Comment + +cmd_fstring = ( + f"sudo -E deluge-console info --detailed --sort-reverse=time_added " + f"{'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {{'' if ID is None else ID}} | perl -nE 'print if /^{field}:/'" + +fstring = f"This string really doesn't need to be an {{{{fstring}}}}, but this one most certainly, absolutely {does}." + +fstring = ( + f"We have to remember to escape {braces}." + " Like {these}." + f" But not {this}." +) + +class A: + class B: + def foo(): + st_error = STError( + f"This string ({string_leaf.value}) appears to be pointless (i.e. has" + " no parent)." + ) + +def foo(): + user_regex = _lazy_re_compile( + r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z" # dot-atom + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)', # quoted-string + re.IGNORECASE) + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', # quoted-string + xyz + ) + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', # quoted-string + xyz + ) + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\n" + "Please note that you cannot serialize things like inner " + "classes. Please move the object into the main module " + "body to use migrations.\n" + "For more information, see " + "https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version())) + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\nPlease note that you cannot serialize things like inner classes. Please move the object into the main module body to use migrations.\nFor more information, see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version())) + +x = ( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + +class Step(StepBase): + def who(self): + self.cmd = 'SR AAAA-CORRECT NAME IS {last_name} {first_name}{middle_name} {title}/P{passenger_association}'.format( + last_name=last_name, + first_name=first_name, + middle_name=middle_name, + title=title, + passenger_association=passenger_association, + ) + +xxxxxxx_xxxxxx_xxxxxxx = xxx( + [ + xxxxxxxxxxxx( + xxxxxx_xxxxxxx=( + '((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx = "xxxxxxxxxxxx")) && ' + # xxxxx xxxxxxxxxxxx xxxx xxx (xxxxxxxxxxxxxxxx) xx x xxxxxxxxx xx xxxxxx. + "(x.bbbbbbbbbbbb.xxx != " + '"xxx:xxx:xxx::cccccccccccc:xxxxxxx-xxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxxxx") && ' + ) + ) + ] +) + +if __name__ == "__main__": + for i in range(4, 8): + cmd = ( + r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk '{print $2}'); do kill $pid; done" + % (i) + ) + +def A(): + def B(): + def C(): + def D(): + def E(): + def F(): + def G(): + assert ( + c_float(val[0][0] / val[0][1]).value + == c_float(value[0][0] / value[0][1]).value + ), "%s didn't roundtrip" % tag + +class xxxxxxxxxxxxxxxxxxxxx(xxxx.xxxxxxxxxxxxx): + def xxxxxxx_xxxxxx(xxxx): + assert xxxxxxx_xxxx in [ + x.xxxxx.xxxxxx.xxxxx.xxxxxx, + x.xxxxx.xxxxxx.xxxxx.xxxx, + ], ("xxxxxxxxxxx xxxxxxx xxxx (xxxxxx xxxx) %x xxx xxxxx" % xxxxxxx_xxxx) + +value.__dict__[ + key +] = "test" # set some Thrift field to non-None in the struct aa bb cc dd ee + +RE_ONE_BACKSLASH = { + "asdf_hjkl_jkl": re.compile( + r"(?>\n" +) + +assert str(suffix_arr) == ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) != ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) <= ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) >= ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) < ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) > ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +assert str(suffix_arr) not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + "3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + "5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + "9. You now have a key to add to `{prefix}set api youtube api_key`" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + "9. You now have a key to add to `{prefix}set api youtube api_key`" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{prefix}set api youtube api_key`" +) + +# It shouldn't matter if the string prefixes are capitalized. +temp_msg = ( + F"{F'{humanize_number(pos)}.': <{pound_len+2}} " + F"{balance: <{bal_len + 5}} " + F"<<{author.display_name}>>\n" +) + +fstring = ( + F"We have to remember to escape {braces}." + " Like {these}." + F" But not {this}." +) + +welcome_to_programming = R"hello," R" world!" + +fstring = F"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one." + +x = F"This is a long string which contains an f-expr that should not split {{{[i for i in range(5)]}}}." + +x = ( + "\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}\N{VARIATION SELECTOR-16}" +) + +xxxxxx_xxx_xxxx_xx_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxx_xxxx_xxxxx = xxxx.xxxxxx.xxxxxxxxx.xxxxxxxxxxxxxxxxxxxx( + xx_xxxxxx={ + "x3_xxxxxxxx": "xxx3_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxxxxxx_xxxxxx_xxxxxxx", + }, +) + +# Regression test for https://github.com/psf/black/issues/3117. +some_dict = { + "something_something": + r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t", +} + +# Regression test for https://github.com/psf/black/issues/3459. +xxxx( + empty_str_as_first_split='' + f'xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx ' + 'xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. ' + f'xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}', + empty_u_str_as_first_split=u'' + f'xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx ' + 'xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. ' + f'xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}', +) + +# Regression test for https://github.com/psf/black/issues/3455. +a_dict = { + "/this/is/a/very/very/very/very/very/very/very/very/very/very/long/key/without/spaces": + # And there is a comment before the value + ("item1", "item2", "item3"), +} + +# Regression test for https://github.com/psf/black/issues/3506. +s = ( + "With single quote: ' " + f" {my_dict['foo']}" + ' With double quote: " ' + f' {my_dict["bar"]}' +) + +s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:\'{my_dict["foo"]}\'' +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -25,20 +25,17 @@ + "Jaguar", + ) + +-stupid_format_method_bug = ( +- "Some really long string that just so happens to be the {} {} to force the 'format'" +- " method to hang over the line length boundary. This is pretty annoying.".format( +- "perfect", "length" +- ) ++stupid_format_method_bug = "Some really long string that just so happens to be the {} {} to force the 'format' method to hang over the line length boundary. This is pretty annoying.".format( ++ "perfect", "length" + ) + + + class A: + def foo(): + os.system( +- "This is a regression test. xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx" +- " xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx" +- " xxxx.".format("xxxxxxxxxx", "xxxxxx", "xxxxxxxxxx") ++ "This is a regression test. xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxxx.".format( ++ "xxxxxxxxxx", "xxxxxx", "xxxxxxxxxx" ++ ) + ) + + +@@ -57,9 +54,11 @@ + class B: + def foo(): + bar( +- "[{}]: xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx={}" +- " xxxx_xxxx_xxxxxxxxxx={}, xxxx={})".format( +- xxxx._xxxxxxxxxxxxxx, xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx, xxxxxxx ++ ( ++ "[{}]: xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx={}" ++ " xxxx_xxxx_xxxxxxxxxx={}, xxxx={})".format( ++ xxxx._xxxxxxxxxxxxxx, xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx, xxxxxxx ++ ) + ), + varX, + varY, +@@ -70,9 +69,10 @@ + def foo(xxxx): + for xxx_xxxx, _xxx_xxx, _xxx_xxxxx, xxx_xxxx in xxxx: + for xxx in xxx_xxxx: +- assert ("x" in xxx) or (xxx in xxx_xxx_xxxxx), ( +- "{0} xxxxxxx xx {1}, xxx {1} xx xxx xx xxxx xx xxx xxxx: xxx xxxx {2}" +- .format(xxx_xxxx, xxx, xxxxxx.xxxxxxx(xxx_xxx_xxxxx)) ++ assert ( ++ ("x" in xxx) or (xxx in xxx_xxx_xxxxx) ++ ), "{0} xxxxxxx xx {1}, xxx {1} xx xxx xx xxxx xx xxx xxxx: xxx xxxx {2}".format( ++ xxx_xxxx, xxx, xxxxxx.xxxxxxx(xxx_xxx_xxxxx) + ) + + +@@ -80,10 +80,11 @@ + def disappearing_comment(): + return ( + ( # xx -x xxxxxxx xx xxx xxxxxxx. +- "{{xxx_xxxxxxxxxx_xxxxxxxx}} xxx xxxx {} {{xxxx}} >&2".format( ++ "{{xxx_xxxxxxxxxx_xxxxxxxx}} xxx xxxx" " {} {{xxxx}} >&2".format( + "{xxxx} {xxxxxx}" + if xxxxx.xx_xxxxxxxxxx +- else ( # Disappearing Comment ++ # Disappearing Comment ++ else ( + "--xxxxxxx --xxxxxx=x --xxxxxx-xxxxx=xxxxxx" + " --xxxxxx-xxxx=xxxxxxxxxxx.xxx" + ) +@@ -113,18 +114,25 @@ + + + func_call_where_string_arg_has_method_call_and_bad_parens( +- "A long string with {}. This string is so long that it is ridiculous. It can't fit" +- " on one line at alllll.".format("formatting"), ++ ( ++ "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll.".format( ++ "formatting" ++ ) ++ ), + ) + + func_call_where_string_arg_has_old_fmt_and_bad_parens( +- "A long string with {}. This string is so long that it is ridiculous. It can't fit" +- " on one line at alllll." % "formatting", ++ ( ++ "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll." ++ % "formatting" ++ ), + ) + + func_call_where_string_arg_has_old_fmt_and_bad_parens( +- "A long string with {}. This {} is so long that it is ridiculous. It can't fit on" +- " one line at alllll." % ("formatting", "string"), ++ ( ++ "A long string with {}. This {} is so long that it is ridiculous. It can't fit on one line at alllll." ++ % ("formatting", "string") ++ ), + ) + + +@@ -132,52 +140,60 @@ + def append(self): + if True: + xxxx.xxxxxxx.xxxxx( +- "xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx" +- % (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx) +- + " %.3f (%s) to %.3f (%s).\n" +- % ( +- xxxx.xxxxxxxxx, +- xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx), +- x, +- xxxx.xxxxxxxxxxxxxx(xx), ++ ( ++ "xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx" ++ % (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx) ++ ) ++ + ( ++ " %.3f (%s) to %.3f (%s).\n" ++ % ( ++ xxxx.xxxxxxxxx, ++ xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx), ++ x, ++ xxxx.xxxxxxxxxxxxxx(xx), ++ ) + ) + ) + + + class A: + def foo(): +- some_func_call( +- "xxxxxxxxxx", +- "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " +- '"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; ' +- "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" ", +- None, +- ("xxxxxxxxxxx",), +- ), ++ ( ++ some_func_call( ++ "xxxxxxxxxx", ++ ( ++ "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " ++ '"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; ' ++ "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" " ++ ), ++ None, ++ ("xxxxxxxxxxx",), ++ ), ++ ) + + + class A: + def foo(): +- some_func_call( +- "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " +- "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; " +- "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" ", +- None, +- ("xxxxxxxxxxx",), +- ), ++ ( ++ some_func_call( ++ ( ++ "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " ++ "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; " ++ "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" " ++ ), ++ None, ++ ("xxxxxxxxxxx",), ++ ), ++ ) + + + xxxxxxx = { +- "xx": ( +- "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} -xx {1} -xx" +- " xxx=xxx_xxxx,xxx_xx,xxx_xxx,xxx_xxxx,xxx_xx,xxx_xxx | xxxxxx -x xxxxxxxx -x" +- " xxxxxxxx -x" +- ), +- "xx": ( +- "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} -xx {1} -xx" +- " xxx=xxx_xxxx_xxx_xxxx,xxx_xx_xxx_xxxx,xxx_xxxx_xxx_xxxx,xxx_xx_xxxx_xxxx,xxx_xxx_xxxx,xxx_xxx_xxxx" +- " xxxx=xxx | xxxxxx -x xxxxxxxx -x xxxxxxxx -x" +- ), ++ "xx": "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} \ ++-xx {1} -xx xxx=xxx_xxxx,xxx_xx,xxx_xxx,xxx_xxxx,xxx_xx,xxx_xxx |\ ++ xxxxxx -x xxxxxxxx -x xxxxxxxx -x", ++ "xx": "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} \ ++-xx {1} -xx xxx=xxx_xxxx_xxx_xxxx,xxx_xx_xxx_xxxx,xxx_xxxx_xxx_xxxx,\ ++xxx_xx_xxxx_xxxx,xxx_xxx_xxxx,xxx_xxx_xxxx xxxx=xxx | xxxxxx -x xxxxxxxx -x xxxxxxxx -x", + } + + +@@ -185,10 +201,10 @@ + def foo(self): + if True: + xxxxx_xxxxxxxxxxxx( +- "xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx" +- " xxxxxxx " +- + "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx" +- .xxxxxx(xxxxxx_xxxxxx_xxx) ++ "xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx xxxxxxx " ++ + "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx".xxxxxx( ++ xxxxxx_xxxxxx_xxx ++ ) + ) + + +@@ -232,39 +248,24 @@ + + some_dictionary = { + "xxxxx006": [ +- ( +- "xxx-xxx" +- " xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx==" +- " xxxxx000 xxxxxxxxxx\n" +- ), +- ( +- "xxx-xxx" +- " xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx==" +- " xxxxx010 xxxxxxxxxx\n" +- ), ++ "xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx== xxxxx000 xxxxxxxxxx\n", ++ "xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx== xxxxx010 xxxxxxxxxx\n", + ], + "xxxxx016": [ +- ( +- "xxx-xxx" +- " xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx==" +- " xxxxx000 xxxxxxxxxx\n" +- ), +- ( +- "xxx-xxx" +- " xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx==" +- " xxxxx010 xxxxxxxxxx\n" +- ), ++ "xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx== xxxxx000 xxxxxxxxxx\n", ++ "xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx== xxxxx010 xxxxxxxxxx\n", + ], + } + + + def foo(): +- xxx_xxx = ( # xxxx xxxxxxxxxx xxxx xx xxxx xx xxx xxxxxxxx xxxxxx xxxxx. +- 'xxxx xxx xxxxxxxx_xxxx xx "xxxxxxxxxx".\n xxx: xxxxxx xxxxxxxx_xxxx=xxxxxxxxxx' +- ) ++ xxx_xxx = ( ++ 'xxxx xxx xxxxxxxx_xxxx xx "xxxxxxxxxx".' ++ "\n xxx: xxxxxx xxxxxxxx_xxxx=xxxxxxxxxx" ++ ) # xxxx xxxxxxxxxx xxxx xx xxxx xx xxx xxxxxxxx xxxxxx xxxxx. + + +-some_tuple = ("some string", "some string which should be joined") ++some_tuple = ("some string", "some string" " which should be joined") + + some_commented_string = ( # This comment stays at the top. + "This string is long but not so long that it needs hahahah toooooo be so greatttt" +@@ -279,36 +280,25 @@ + ) + + lpar_and_rpar_have_comments = func_call( # LPAR Comment +- "Long really ridiculous type of string that shouldn't really even exist at all. I" +- " mean commmme onnn!!!", # Comma Comment ++ "Long really ridiculous type of string that shouldn't really even exist at all. I mean commmme onnn!!!", # Comma Comment + ) # RPAR Comment + + cmd_fstring = ( +- "sudo -E deluge-console info --detailed --sort-reverse=time_added " ++ f"sudo -E deluge-console info --detailed --sort-reverse=time_added " + f"{'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + ) + +-cmd_fstring = ( +- "sudo -E deluge-console info --detailed --sort-reverse=time_added" +- f" {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +-) ++cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + +-cmd_fstring = ( +- "sudo -E deluge-console info --detailed --sort-reverse=time_added" +- f" {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +-) ++cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + +-cmd_fstring = ( +- "sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is" +- f" None else ID}} | perl -nE 'print if /^{field}:/'" +-) ++cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {{'' if ID is None else ID}} | perl -nE 'print if /^{field}:/'" + ++fstring = f"This string really doesn't need to be an {{{{fstring}}}}, but this one most certainly, absolutely {does}." ++ + fstring = ( +- "This string really doesn't need to be an {{fstring}}, but this one most" +- f" certainly, absolutely {does}." ++ f"We have to remember to escape {braces}." " Like {these}." f" But not {this}." + ) +- +-fstring = f"We have to remember to escape {braces}. Like {{these}}. But not {this}." + + + class A: +@@ -364,10 +354,7 @@ + def foo(): + if not hasattr(module, name): + raise ValueError( +- "Could not find object %s in %s.\nPlease note that you cannot" +- " serialize things like inner classes. Please move the object into" +- " the main module body to use migrations.\nFor more information," +- " see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" ++ "Could not find object %s in %s.\nPlease note that you cannot serialize things like inner classes. Please move the object into the main module body to use migrations.\nFor more information, see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version()) + ) + +@@ -382,23 +369,19 @@ + + class Step(StepBase): + def who(self): +- self.cmd = ( +- "SR AAAA-CORRECT NAME IS {last_name} {first_name}{middle_name}" +- " {title}/P{passenger_association}".format( +- last_name=last_name, +- first_name=first_name, +- middle_name=middle_name, +- title=title, +- passenger_association=passenger_association, +- ) ++ self.cmd = "SR AAAA-CORRECT NAME IS {last_name} {first_name}{middle_name} {title}/P{passenger_association}".format( ++ last_name=last_name, ++ first_name=first_name, ++ middle_name=middle_name, ++ title=title, ++ passenger_association=passenger_association, + ) + + + xxxxxxx_xxxxxx_xxxxxxx = xxx([ + xxxxxxxxxxxx( + xxxxxx_xxxxxxx=( +- '((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx =' +- ' "xxxxxxxxxxxx")) && ' ++ '((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx = "xxxxxxxxxxxx")) && ' + # xxxxx xxxxxxxxxxxx xxxx xxx (xxxxxxxxxxxxxxxx) xx x xxxxxxxxx xx xxxxxx. + "(x.bbbbbbbbbbbb.xxx != " + '"xxx:xxx:xxx::cccccccccccc:xxxxxxx-xxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxxxx") && ' +@@ -409,8 +392,8 @@ + if __name__ == "__main__": + for i in range(4, 8): + cmd = ( +- r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk" +- r" '{print $2}'); do kill $pid; done" % (i) ++ r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk '{print $2}'); do kill $pid; done" ++ % (i) + ) + + +@@ -432,9 +415,7 @@ + assert xxxxxxx_xxxx in [ + x.xxxxx.xxxxxx.xxxxx.xxxxxx, + x.xxxxx.xxxxxx.xxxxx.xxxx, +- ], ( +- "xxxxxxxxxxx xxxxxxx xxxx (xxxxxx xxxx) %x xxx xxxxx" % xxxxxxx_xxxx +- ) ++ ], "xxxxxxxxxxx xxxxxxx xxxx (xxxxxx xxxx) %x xxx xxxxx" % xxxxxxx_xxxx + + + value.__dict__[key] = ( +@@ -449,8 +430,7 @@ + + RE_TWO_BACKSLASHES = { + "asdf_hjkl_jkl": re.compile( +- r"(?>\n" + ) + +-assert ( +- str(suffix_arr) +- == "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " ++assert str(suffix_arr) == ( ++ "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" + ) +-assert ( +- str(suffix_arr) +- != "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " ++assert str(suffix_arr) != ( ++ "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" + ) +-assert ( +- str(suffix_arr) +- <= "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " ++assert str(suffix_arr) <= ( ++ "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" + ) +-assert ( +- str(suffix_arr) +- >= "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " ++assert str(suffix_arr) >= ( ++ "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" + ) +-assert ( +- str(suffix_arr) +- < "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " ++assert str(suffix_arr) < ( ++ "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" + ) +-assert ( +- str(suffix_arr) +- > "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " ++assert str(suffix_arr) > ( ++ "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" + ) + assert ( + str(suffix_arr) +- in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$'," +- " 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$'," +- " 'ykangaroo$']" ++ in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" + ) + assert ( + str(suffix_arr) +- not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$'," +- " 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$'," +- " 'rykangaroo$', 'ykangaroo$']" ++ not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" + ) + message = ( + f"1. Go to Google Developers Console and log in with your Google account." +- f"(https://console.developers.google.com/)" +- f"2. You should be prompted to create a new project (name does not matter)." +- f"3. Click on Enable APIs and Services at the top." +- f"4. In the list of APIs choose or search for YouTube Data API v3 and " +- f"click on it. Choose Enable." +- f"5. Click on Credentials on the left navigation bar." +- f"6. Click on Create Credential at the top." +- f'7. At the top click the link for "API key".' +- f"8. No application restrictions are needed. Click Create at the bottom." +- f"9. You now have a key to add to `{{prefix}}set api youtube api_key`" ++ "(https://console.developers.google.com/)" ++ "2. You should be prompted to create a new project (name does not matter)." ++ "3. Click on Enable APIs and Services at the top." ++ "4. In the list of APIs choose or search for YouTube Data API v3 and " ++ "click on it. Choose Enable." ++ "5. Click on Credentials on the left navigation bar." ++ "6. Click on Create Credential at the top." ++ '7. At the top click the link for "API key".' ++ "8. No application restrictions are needed. Click Create at the bottom." ++ "9. You now have a key to add to `{prefix}set api youtube api_key`" + ) + message = ( + f"1. Go to Google Developers Console and log in with your Google account." +- f"(https://console.developers.google.com/)" +- f"2. You should be prompted to create a new project (name does not matter)." ++ "(https://console.developers.google.com/)" ++ "2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." +- f"4. In the list of APIs choose or search for YouTube Data API v3 and " +- f"click on it. Choose Enable." ++ "4. In the list of APIs choose or search for YouTube Data API v3 and " ++ "click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." +- f"6. Click on Create Credential at the top." +- f'7. At the top click the link for "API key".' +- f"8. No application restrictions are needed. Click Create at the bottom." +- f"9. You now have a key to add to `{{prefix}}set api youtube api_key`" ++ "6. Click on Create Credential at the top." ++ '7. At the top click the link for "API key".' ++ "8. No application restrictions are needed. Click Create at the bottom." ++ "9. You now have a key to add to `{prefix}set api youtube api_key`" + ) + message = ( +- "1. Go to Google Developers Console and log in with your Google account." ++ f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." +- "3. Click on Enable APIs and Services at the top." ++ f"3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." +- "5. Click on Credentials on the left navigation bar." ++ f"5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." +@@ -613,55 +579,40 @@ + f"<<{author.display_name}>>\n" + ) + +-fstring = f"We have to remember to escape {braces}. Like {{these}}. But not {this}." ++fstring = ( ++ f"We have to remember to escape {braces}." " Like {these}." f" But not {this}." ++) + + welcome_to_programming = R"hello," R" world!" + +-fstring = ( +- f"f-strings definitely make things more {difficult} than they need to be for" +- " {black}. But boy they sure are handy. The problem is that some lines will need" +- f" to have the 'f' whereas others do not. This {line}, for example, needs one." +-) ++fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one." + +-x = ( +- "This is a long string which contains an f-expr that should not split" +- f" {{{[i for i in range(5)]}}}." +-) ++x = f"This is a long string which contains an f-expr that should not split {{{[i for i in range(5)]}}}." + +-x = ( +- "\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}\N{VARIATION SELECTOR-16}" +-) ++x = "\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}\N{VARIATION SELECTOR-16}" + + xxxxxx_xxx_xxxx_xx_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxx_xxxx_xxxxx = xxxx.xxxxxx.xxxxxxxxx.xxxxxxxxxxxxxxxxxxxx( + xx_xxxxxx={ +- "x3_xxxxxxxx": ( +- "xxx3_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxxxxxx_xxxxxx_xxxxxxx" +- ), ++ "x3_xxxxxxxx": "xxx3_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxxxxxx_xxxxxx_xxxxxxx", + }, + ) + + # Regression test for https://github.com/psf/black/issues/3117. + some_dict = { +- "something_something": ( +- r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" +- r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" +- ), ++ "something_something": r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" ++ r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t", + } + + # Regression test for https://github.com/psf/black/issues/3459. + xxxx( +- empty_str_as_first_split=( +- "" +- f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " +- "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " +- f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}" +- ), +- empty_u_str_as_first_split=( +- "" +- f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " +- "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " +- f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}" +- ), ++ empty_str_as_first_split="" ++ f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " ++ "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " ++ f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}", ++ empty_u_str_as_first_split="" ++ f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " ++ "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " ++ f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}", + ) + + # Regression test for https://github.com/psf/black/issues/3455. +@@ -672,9 +623,11 @@ + } + + # Regression test for https://github.com/psf/black/issues/3506. +-s = f"With single quote: ' {my_dict['foo']} With double quote: \" {my_dict['bar']}" +- + s = ( +- "Lorem Ipsum is simply dummy text of the printing and typesetting" +- f" industry:'{my_dict['foo']}'" ++ "With single quote: ' " ++ f" {my_dict['foo']}" ++ ' With double quote: " ' ++ f' {my_dict["bar"]}' + ) ++ ++s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:\'{my_dict["foo"]}\'' +``` + +## Ruff Output + +```python +class A: + def foo(): + result = type(message)("") + + +# Don't merge multiline (e.g. triple-quoted) strings. +def foo(): + query = ( + """SELECT xxxxxxxxxxxxxxxxxxxx(xxx)""" + """ FROM xxxxxxxxxxxxxxxx WHERE xxxxxxxxxx AND xxx <> xxxxxxxxxxxxxx()""" + ) + + +# There was a bug where tuples were being identified as long strings. +long_tuple = ( + "Apple", + "Berry", + "Cherry", + "Dill", + "Evergreen", + "Fig", + "Grape", + "Harry", + "Iglu", + "Jaguar", +) + +stupid_format_method_bug = "Some really long string that just so happens to be the {} {} to force the 'format' method to hang over the line length boundary. This is pretty annoying.".format( + "perfect", "length" +) + + +class A: + def foo(): + os.system( + "This is a regression test. xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxxx.".format( + "xxxxxxxxxx", "xxxxxx", "xxxxxxxxxx" + ) + ) + + +class A: + def foo(): + XXXXXXXXXXXX.append(( + "xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx, xxxx_xxxx_xxxxxxxxxx={})".format( + xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx + ), + my_var, + my_other_var, + )) + + +class A: + class B: + def foo(): + bar( + ( + "[{}]: xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx={}" + " xxxx_xxxx_xxxxxxxxxx={}, xxxx={})".format( + xxxx._xxxxxxxxxxxxxx, xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx, xxxxxxx + ) + ), + varX, + varY, + varZ, + ) + + +def foo(xxxx): + for xxx_xxxx, _xxx_xxx, _xxx_xxxxx, xxx_xxxx in xxxx: + for xxx in xxx_xxxx: + assert ( + ("x" in xxx) or (xxx in xxx_xxx_xxxxx) + ), "{0} xxxxxxx xx {1}, xxx {1} xx xxx xx xxxx xx xxx xxxx: xxx xxxx {2}".format( + xxx_xxxx, xxx, xxxxxx.xxxxxxx(xxx_xxx_xxxxx) + ) + + +class A: + def disappearing_comment(): + return ( + ( # xx -x xxxxxxx xx xxx xxxxxxx. + "{{xxx_xxxxxxxxxx_xxxxxxxx}} xxx xxxx" " {} {{xxxx}} >&2".format( + "{xxxx} {xxxxxx}" + if xxxxx.xx_xxxxxxxxxx + # Disappearing Comment + else ( + "--xxxxxxx --xxxxxx=x --xxxxxx-xxxxx=xxxxxx" + " --xxxxxx-xxxx=xxxxxxxxxxx.xxx" + ) + ) + ), + (x, y, z), + ) + + +class A: + class B: + def foo(): + xxxxx_xxxx( + xx, + "\t" + "@xxxxxx '{xxxx_xxx}\t' > {xxxxxx_xxxx}.xxxxxxx;" + "{xxxx_xxx} >> {xxxxxx_xxxx}.xxxxxxx 2>&1; xx=$$?;" + "xxxx $$xx".format( + xxxx_xxx=xxxx_xxxxxxx, + xxxxxx_xxxx=xxxxxxx + "/" + xxxx_xxx_xxxx, + x=xxx_xxxxx_xxxxx_xxx, + ), + x, + y, + z, + ) + + +func_call_where_string_arg_has_method_call_and_bad_parens( + ( + "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll.".format( + "formatting" + ) + ), +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + ( + "A long string with {}. This string is so long that it is ridiculous. It can't fit on one line at alllll." + % "formatting" + ), +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + ( + "A long string with {}. This {} is so long that it is ridiculous. It can't fit on one line at alllll." + % ("formatting", "string") + ), +) + + +class A: + def append(self): + if True: + xxxx.xxxxxxx.xxxxx( + ( + "xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx" + % (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx) + ) + + ( + " %.3f (%s) to %.3f (%s).\n" + % ( + xxxx.xxxxxxxxx, + xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx), + x, + xxxx.xxxxxxxxxxxxxx(xx), + ) + ) + ) + + +class A: + def foo(): + ( + some_func_call( + "xxxxxxxxxx", + ( + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + '"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; ' + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" " + ), + None, + ("xxxxxxxxxxx",), + ), + ) + + +class A: + def foo(): + ( + some_func_call( + ( + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; " + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" " + ), + None, + ("xxxxxxxxxxx",), + ), + ) + + +xxxxxxx = { + "xx": "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} \ +-xx {1} -xx xxx=xxx_xxxx,xxx_xx,xxx_xxx,xxx_xxxx,xxx_xx,xxx_xxx |\ + xxxxxx -x xxxxxxxx -x xxxxxxxx -x", + "xx": "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} \ +-xx {1} -xx xxx=xxx_xxxx_xxx_xxxx,xxx_xx_xxx_xxxx,xxx_xxxx_xxx_xxxx,\ +xxx_xx_xxxx_xxxx,xxx_xxx_xxxx,xxx_xxx_xxxx xxxx=xxx | xxxxxx -x xxxxxxxx -x xxxxxxxx -x", +} + + +class A: + def foo(self): + if True: + xxxxx_xxxxxxxxxxxx( + "xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx xxxxxxx " + + "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx".xxxxxx( + xxxxxx_xxxxxx_xxx + ) + ) + + +class A: + class B: + def foo(): + row = { + "xxxxxxxxxxxxxxx": xxxxxx_xxxxx_xxxx, + # 'xxxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxx' + "xxxxxxxxxx": xxxxx_xxxxx, + } + + +class A: + def xxxx_xxx_xx_xxxxxxxxxx_xxxx_xxxxxxxxx(xxxx): + xxxxxxxx = [ + xxxxxxxxxxxxxxxx( + "xxxx", + xxxxxxxxxxx={ + "xxxx": 1.0, + }, + xxxxxx={"xxxxxx 1": xxxxxx(xxxx="xxxxxx 1", xxxxxx=600.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + "xxxxxxx", + xxxxxxxxxxx={ + "xxxx": 1.0, + }, + xxxxxx={"xxxxxx 1": xxxxxx(xxxx="xxxxxx 1", xxxxxx=200.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + "xxxx", + ), + ] + + +some_dictionary = { + "xxxxx006": [ + "xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx== xxxxx000 xxxxxxxxxx\n", + "xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx== xxxxx010 xxxxxxxxxx\n", + ], + "xxxxx016": [ + "xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx== xxxxx000 xxxxxxxxxx\n", + "xxx-xxx xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx== xxxxx010 xxxxxxxxxx\n", + ], +} + + +def foo(): + xxx_xxx = ( + 'xxxx xxx xxxxxxxx_xxxx xx "xxxxxxxxxx".' + "\n xxx: xxxxxx xxxxxxxx_xxxx=xxxxxxxxxx" + ) # xxxx xxxxxxxxxx xxxx xx xxxx xx xxx xxxxxxxx xxxxxx xxxxx. + + +some_tuple = ("some string", "some string" " which should be joined") + +some_commented_string = ( # This comment stays at the top. + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at" + " allllllllllll".format("ha") # comments here are fine +) + +some_commented_string = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" # But these + " {} that I just can't think of any more good words to say about it at" # comments will stay + " allllllllllll".format("ha") # comments here are fine +) + +lpar_and_rpar_have_comments = func_call( # LPAR Comment + "Long really ridiculous type of string that shouldn't really even exist at all. I mean commmme onnn!!!", # Comma Comment +) # RPAR Comment + +cmd_fstring = ( + f"sudo -E deluge-console info --detailed --sort-reverse=time_added " + f"{'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'" + +cmd_fstring = f"sudo -E deluge-console info --detailed --sort-reverse=time_added {{'' if ID is None else ID}} | perl -nE 'print if /^{field}:/'" + +fstring = f"This string really doesn't need to be an {{{{fstring}}}}, but this one most certainly, absolutely {does}." + +fstring = ( + f"We have to remember to escape {braces}." " Like {these}." f" But not {this}." +) + + +class A: + class B: + def foo(): + st_error = STError( + f"This string ({string_leaf.value}) appears to be pointless (i.e. has" + " no parent)." + ) + + +def foo(): + user_regex = _lazy_re_compile( + r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z" # dot-atom + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)', # quoted-string + re.IGNORECASE, + ) + + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # quoted-string + xyz, + ) + + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # quoted-string + xyz, + ) + + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\n" + "Please note that you cannot serialize things like inner " + "classes. Please move the object into the main module " + "body to use migrations.\n" + "For more information, see " + "https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version()) + ) + + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\nPlease note that you cannot serialize things like inner classes. Please move the object into the main module body to use migrations.\nFor more information, see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version()) + ) + + +x = ( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + + +class Step(StepBase): + def who(self): + self.cmd = "SR AAAA-CORRECT NAME IS {last_name} {first_name}{middle_name} {title}/P{passenger_association}".format( + last_name=last_name, + first_name=first_name, + middle_name=middle_name, + title=title, + passenger_association=passenger_association, + ) + + +xxxxxxx_xxxxxx_xxxxxxx = xxx([ + xxxxxxxxxxxx( + xxxxxx_xxxxxxx=( + '((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx = "xxxxxxxxxxxx")) && ' + # xxxxx xxxxxxxxxxxx xxxx xxx (xxxxxxxxxxxxxxxx) xx x xxxxxxxxx xx xxxxxx. + "(x.bbbbbbbbbbbb.xxx != " + '"xxx:xxx:xxx::cccccccccccc:xxxxxxx-xxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxxxx") && ' + ) + ) +]) + +if __name__ == "__main__": + for i in range(4, 8): + cmd = ( + r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk '{print $2}'); do kill $pid; done" + % (i) + ) + + +def A(): + def B(): + def C(): + def D(): + def E(): + def F(): + def G(): + assert ( + c_float(val[0][0] / val[0][1]).value + == c_float(value[0][0] / value[0][1]).value + ), "%s didn't roundtrip" % tag + + +class xxxxxxxxxxxxxxxxxxxxx(xxxx.xxxxxxxxxxxxx): + def xxxxxxx_xxxxxx(xxxx): + assert xxxxxxx_xxxx in [ + x.xxxxx.xxxxxx.xxxxx.xxxxxx, + x.xxxxx.xxxxxx.xxxxx.xxxx, + ], "xxxxxxxxxxx xxxxxxx xxxx (xxxxxx xxxx) %x xxx xxxxx" % xxxxxxx_xxxx + + +value.__dict__[key] = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) + +RE_ONE_BACKSLASH = { + "asdf_hjkl_jkl": re.compile( + r"(?>\n" +) + +assert str(suffix_arr) == ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) != ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) <= ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) >= ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) < ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert str(suffix_arr) > ( + "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + "3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + "5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + "9. You now have a key to add to `{prefix}set api youtube api_key`" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + "9. You now have a key to add to `{prefix}set api youtube api_key`" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{prefix}set api youtube api_key`" +) + +# It shouldn't matter if the string prefixes are capitalized. +temp_msg = ( + f"{F'{humanize_number(pos)}.': <{pound_len+2}} " + f"{balance: <{bal_len + 5}} " + f"<<{author.display_name}>>\n" +) + +fstring = ( + f"We have to remember to escape {braces}." " Like {these}." f" But not {this}." +) + +welcome_to_programming = R"hello," R" world!" + +fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one." + +x = f"This is a long string which contains an f-expr that should not split {{{[i for i in range(5)]}}}." + +x = "\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}\N{VARIATION SELECTOR-16}" + +xxxxxx_xxx_xxxx_xx_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxx_xxxx_xxxxx = xxxx.xxxxxx.xxxxxxxxx.xxxxxxxxxxxxxxxxxxxx( + xx_xxxxxx={ + "x3_xxxxxxxx": "xxx3_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxxxxxx_xxxxxx_xxxxxxx", + }, +) + +# Regression test for https://github.com/psf/black/issues/3117. +some_dict = { + "something_something": r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t", +} + +# Regression test for https://github.com/psf/black/issues/3459. +xxxx( + empty_str_as_first_split="" + f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " + "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " + f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}", + empty_u_str_as_first_split="" + f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " + "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " + f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}", +) + +# Regression test for https://github.com/psf/black/issues/3455. +a_dict = { + "/this/is/a/very/very/very/very/very/very/very/very/very/very/long/key/without/spaces": + # And there is a comment before the value + ("item1", "item2", "item3"), +} + +# Regression test for https://github.com/psf/black/issues/3506. +s = ( + "With single quote: ' " + f" {my_dict['foo']}" + ' With double quote: " ' + f' {my_dict["bar"]}' +) + +s = f'Lorem Ipsum is simply dummy text of the printing and typesetting industry:\'{my_dict["foo"]}\'' +``` + +## Black Output + +```python +class A: + def foo(): + result = type(message)("") + + +# Don't merge multiline (e.g. triple-quoted) strings. +def foo(): + query = ( + """SELECT xxxxxxxxxxxxxxxxxxxx(xxx)""" + """ FROM xxxxxxxxxxxxxxxx WHERE xxxxxxxxxx AND xxx <> xxxxxxxxxxxxxx()""" + ) + + +# There was a bug where tuples were being identified as long strings. +long_tuple = ( + "Apple", + "Berry", + "Cherry", + "Dill", + "Evergreen", + "Fig", + "Grape", + "Harry", + "Iglu", + "Jaguar", +) + +stupid_format_method_bug = ( + "Some really long string that just so happens to be the {} {} to force the 'format'" + " method to hang over the line length boundary. This is pretty annoying.".format( + "perfect", "length" + ) +) + + +class A: + def foo(): + os.system( + "This is a regression test. xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx" + " xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx xxx" + " xxxx.".format("xxxxxxxxxx", "xxxxxx", "xxxxxxxxxx") + ) + + +class A: + def foo(): + XXXXXXXXXXXX.append(( + "xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx, xxxx_xxxx_xxxxxxxxxx={})".format( + xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx + ), + my_var, + my_other_var, + )) + + +class A: + class B: + def foo(): + bar( + "[{}]: xxx_xxxxxxxxxx(xxxxx={}, xxxx={}, xxxxx={}" + " xxxx_xxxx_xxxxxxxxxx={}, xxxx={})".format( + xxxx._xxxxxxxxxxxxxx, xxxxx, xxxx, xxxx_xxxx_xxxxxxxxxx, xxxxxxx + ), + varX, + varY, + varZ, + ) + + +def foo(xxxx): + for xxx_xxxx, _xxx_xxx, _xxx_xxxxx, xxx_xxxx in xxxx: + for xxx in xxx_xxxx: + assert ("x" in xxx) or (xxx in xxx_xxx_xxxxx), ( + "{0} xxxxxxx xx {1}, xxx {1} xx xxx xx xxxx xx xxx xxxx: xxx xxxx {2}" + .format(xxx_xxxx, xxx, xxxxxx.xxxxxxx(xxx_xxx_xxxxx)) + ) + + +class A: + def disappearing_comment(): + return ( + ( # xx -x xxxxxxx xx xxx xxxxxxx. + "{{xxx_xxxxxxxxxx_xxxxxxxx}} xxx xxxx {} {{xxxx}} >&2".format( + "{xxxx} {xxxxxx}" + if xxxxx.xx_xxxxxxxxxx + else ( # Disappearing Comment + "--xxxxxxx --xxxxxx=x --xxxxxx-xxxxx=xxxxxx" + " --xxxxxx-xxxx=xxxxxxxxxxx.xxx" + ) + ) + ), + (x, y, z), + ) + + +class A: + class B: + def foo(): + xxxxx_xxxx( + xx, + "\t" + "@xxxxxx '{xxxx_xxx}\t' > {xxxxxx_xxxx}.xxxxxxx;" + "{xxxx_xxx} >> {xxxxxx_xxxx}.xxxxxxx 2>&1; xx=$$?;" + "xxxx $$xx".format( + xxxx_xxx=xxxx_xxxxxxx, + xxxxxx_xxxx=xxxxxxx + "/" + xxxx_xxx_xxxx, + x=xxx_xxxxx_xxxxx_xxx, + ), + x, + y, + z, + ) + + +func_call_where_string_arg_has_method_call_and_bad_parens( + "A long string with {}. This string is so long that it is ridiculous. It can't fit" + " on one line at alllll.".format("formatting"), +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + "A long string with {}. This string is so long that it is ridiculous. It can't fit" + " on one line at alllll." % "formatting", +) + +func_call_where_string_arg_has_old_fmt_and_bad_parens( + "A long string with {}. This {} is so long that it is ridiculous. It can't fit on" + " one line at alllll." % ("formatting", "string"), +) + + +class A: + def append(self): + if True: + xxxx.xxxxxxx.xxxxx( + "xxxxxxxxxx xxxx xx xxxxxx(%x) xx %x xxxx xx xxx %x.xx" + % (len(self) + 1, xxxx.xxxxxxxxxx, xxxx.xxxxxxxxxx) + + " %.3f (%s) to %.3f (%s).\n" + % ( + xxxx.xxxxxxxxx, + xxxx.xxxxxxxxxxxxxx(xxxx.xxxxxxxxx), + x, + xxxx.xxxxxxxxxxxxxx(xx), + ) + ) + + +class A: + def foo(): + some_func_call( + "xxxxxxxxxx", + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + '"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; ' + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" ", + None, + ("xxxxxxxxxxx",), + ), + + +class A: + def foo(): + some_func_call( + "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x " + "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; " + "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" ", + None, + ("xxxxxxxxxxx",), + ), + + +xxxxxxx = { + "xx": ( + "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} -xx {1} -xx" + " xxx=xxx_xxxx,xxx_xx,xxx_xxx,xxx_xxxx,xxx_xx,xxx_xxx | xxxxxx -x xxxxxxxx -x" + " xxxxxxxx -x" + ), + "xx": ( + "xxxx xxxxxxx xxxxxxxxx -x xxx -x /xxx/{0} -x xxx,xxx -xx {1} -xx {1} -xx" + " xxx=xxx_xxxx_xxx_xxxx,xxx_xx_xxx_xxxx,xxx_xxxx_xxx_xxxx,xxx_xx_xxxx_xxxx,xxx_xxx_xxxx,xxx_xxx_xxxx" + " xxxx=xxx | xxxxxx -x xxxxxxxx -x xxxxxxxx -x" + ), +} + + +class A: + def foo(self): + if True: + xxxxx_xxxxxxxxxxxx( + "xxx xxxxxx xxx xxxxxxxxx.xx xx xxxxxxxx. xxx xxxxxxxxxxxxx.xx" + " xxxxxxx " + + "xx xxxxxx xxxxxx xxxxxx xx xxxxxxx xxx xxx ${0} xx x xxxxxxxx xxxxx" + .xxxxxx(xxxxxx_xxxxxx_xxx) + ) + + +class A: + class B: + def foo(): + row = { + "xxxxxxxxxxxxxxx": xxxxxx_xxxxx_xxxx, + # 'xxxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxxx' + # 'xxxxxxxxxxxxxxxxx' + "xxxxxxxxxx": xxxxx_xxxxx, + } + + +class A: + def xxxx_xxx_xx_xxxxxxxxxx_xxxx_xxxxxxxxx(xxxx): + xxxxxxxx = [ + xxxxxxxxxxxxxxxx( + "xxxx", + xxxxxxxxxxx={ + "xxxx": 1.0, + }, + xxxxxx={"xxxxxx 1": xxxxxx(xxxx="xxxxxx 1", xxxxxx=600.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + "xxxxxxx", + xxxxxxxxxxx={ + "xxxx": 1.0, + }, + xxxxxx={"xxxxxx 1": xxxxxx(xxxx="xxxxxx 1", xxxxxx=200.0)}, + xxxxxxxx_xxxxxxx=0.0, + ), + xxxxxxxxxxxxxxxx( + "xxxx", + ), + ] + + +some_dictionary = { + "xxxxx006": [ + ( + "xxx-xxx" + " xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx==" + " xxxxx000 xxxxxxxxxx\n" + ), + ( + "xxx-xxx" + " xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx==" + " xxxxx010 xxxxxxxxxx\n" + ), + ], + "xxxxx016": [ + ( + "xxx-xxx" + " xxxxx3xxxx1xx2xxxxxxxxxxxxxx0xx6xxxxxxxxxx2xxxxxx9xxxxxxxxxx0xxxxx1xxx2x/xx9xx6+x+xxxxxxxxxxxxxx4xxxxxxxxxxxxxxxxxxxxx43xxx2xx2x4x++xxx6xxxxxxxxx+xxxxx/xx9x+xxxxxxxxxxxxxx8x15xxxxxxxxxxxxxxxxx82xx/xxxxxxxxxxxxxx/x5xxxxxxxxxxxxxx6xxxxxx74x4/xxx4x+xxxxxxxxx2xxxxxxxx87xxxxx4xxxxxxxx3xx0xxxxx4xxx1xx9xx5xxxxxxx/xxxxx5xx6xx4xxxx1x/x2xxxxxxxxxxxx64xxxxxxx1x0xx5xxxxxxxxxxxxxx==" + " xxxxx000 xxxxxxxxxx\n" + ), + ( + "xxx-xxx" + " xxxxx3xxxx1xx2xxxxxxxxxxxxxx6xxxxxxxxxxxxxx9xxxxxxxxxxxxx3xxx9xxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx2xxxx2xxx6xxxxx/xx54xxxxxxxxx4xxx3xxxxxx9xx3xxxxx39xxxxxxxxx5xx91xxxx7xxxxxx8xxxxxxxxxxxxxxxx9xxx93xxxxxxxxxxxxxxxxx7xxx8xx8xx4/x1xxxxx1x3xxxxxxxxxxxxx3xxxxxx9xx4xx4x7xxxxxxxxxxxxx1xxxxxxxxx7xxxxxxxxxxxxxx4xx6xxxxxxxxx9xxx7xxxx2xxxxxxxxxxxxxxxxxxxxxx8xxxxxxxxxxxxxxxxxxxx6xx==" + " xxxxx010 xxxxxxxxxx\n" + ), + ], +} + + +def foo(): + xxx_xxx = ( # xxxx xxxxxxxxxx xxxx xx xxxx xx xxx xxxxxxxx xxxxxx xxxxx. + 'xxxx xxx xxxxxxxx_xxxx xx "xxxxxxxxxx".\n xxx: xxxxxx xxxxxxxx_xxxx=xxxxxxxxxx' + ) + + +some_tuple = ("some string", "some string which should be joined") + +some_commented_string = ( # This comment stays at the top. + "This string is long but not so long that it needs hahahah toooooo be so greatttt" + " {} that I just can't think of any more good words to say about it at" + " allllllllllll".format("ha") # comments here are fine +) + +some_commented_string = ( + "This string is long but not so long that it needs hahahah toooooo be so greatttt" # But these + " {} that I just can't think of any more good words to say about it at" # comments will stay + " allllllllllll".format("ha") # comments here are fine +) + +lpar_and_rpar_have_comments = func_call( # LPAR Comment + "Long really ridiculous type of string that shouldn't really even exist at all. I" + " mean commmme onnn!!!", # Comma Comment +) # RPAR Comment + +cmd_fstring = ( + "sudo -E deluge-console info --detailed --sort-reverse=time_added " + f"{'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = ( + "sudo -E deluge-console info --detailed --sort-reverse=time_added" + f" {'' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = ( + "sudo -E deluge-console info --detailed --sort-reverse=time_added" + f" {'{{}}' if ID is None else ID} | perl -nE 'print if /^{field}:/'" +) + +cmd_fstring = ( + "sudo -E deluge-console info --detailed --sort-reverse=time_added {'' if ID is" + f" None else ID}} | perl -nE 'print if /^{field}:/'" +) + +fstring = ( + "This string really doesn't need to be an {{fstring}}, but this one most" + f" certainly, absolutely {does}." +) + +fstring = f"We have to remember to escape {braces}. Like {{these}}. But not {this}." + + +class A: + class B: + def foo(): + st_error = STError( + f"This string ({string_leaf.value}) appears to be pointless (i.e. has" + " no parent)." + ) + + +def foo(): + user_regex = _lazy_re_compile( + r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z" # dot-atom + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)', # quoted-string + re.IGNORECASE, + ) + + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # quoted-string + xyz, + ) + + +def foo(): + user_regex = _lazy_re_compile( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # dot-atom + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # quoted-string + xyz, + ) + + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\n" + "Please note that you cannot serialize things like inner " + "classes. Please move the object into the main module " + "body to use migrations.\n" + "For more information, see " + "https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version()) + ) + + +class A: + class B: + def foo(): + if not hasattr(module, name): + raise ValueError( + "Could not find object %s in %s.\nPlease note that you cannot" + " serialize things like inner classes. Please move the object into" + " the main module body to use migrations.\nFor more information," + " see https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values" + % (name, module_name, get_docs_version()) + ) + + +x = ( + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +) + + +class Step(StepBase): + def who(self): + self.cmd = ( + "SR AAAA-CORRECT NAME IS {last_name} {first_name}{middle_name}" + " {title}/P{passenger_association}".format( + last_name=last_name, + first_name=first_name, + middle_name=middle_name, + title=title, + passenger_association=passenger_association, + ) + ) + + +xxxxxxx_xxxxxx_xxxxxxx = xxx([ + xxxxxxxxxxxx( + xxxxxx_xxxxxxx=( + '((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx =' + ' "xxxxxxxxxxxx")) && ' + # xxxxx xxxxxxxxxxxx xxxx xxx (xxxxxxxxxxxxxxxx) xx x xxxxxxxxx xx xxxxxx. + "(x.bbbbbbbbbbbb.xxx != " + '"xxx:xxx:xxx::cccccccccccc:xxxxxxx-xxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxxxx") && ' + ) + ) +]) + +if __name__ == "__main__": + for i in range(4, 8): + cmd = ( + r"for pid in $(ps aux | grep paster | grep -v grep | grep '\-%d' | awk" + r" '{print $2}'); do kill $pid; done" % (i) + ) + + +def A(): + def B(): + def C(): + def D(): + def E(): + def F(): + def G(): + assert ( + c_float(val[0][0] / val[0][1]).value + == c_float(value[0][0] / value[0][1]).value + ), "%s didn't roundtrip" % tag + + +class xxxxxxxxxxxxxxxxxxxxx(xxxx.xxxxxxxxxxxxx): + def xxxxxxx_xxxxxx(xxxx): + assert xxxxxxx_xxxx in [ + x.xxxxx.xxxxxx.xxxxx.xxxxxx, + x.xxxxx.xxxxxx.xxxxx.xxxx, + ], ( + "xxxxxxxxxxx xxxxxxx xxxx (xxxxxx xxxx) %x xxx xxxxx" % xxxxxxx_xxxx + ) + + +value.__dict__[key] = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) + +RE_ONE_BACKSLASH = { + "asdf_hjkl_jkl": re.compile( + r"(?>\n" +) + +assert ( + str(suffix_arr) + == "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + != "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + <= "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + >= "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + < "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + > "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', " + "'grykangaroo$', 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', " + "'o$', 'oo$', 'roo$', 'rykangaroo$', 'ykangaroo$']" +) +assert ( + str(suffix_arr) + in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$'," + " 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$', 'rykangaroo$'," + " 'ykangaroo$']" +) +assert ( + str(suffix_arr) + not in "['$', 'angaroo$', 'angrykangaroo$', 'aroo$', 'garoo$', 'grykangaroo$'," + " 'kangaroo$', 'ngaroo$', 'ngrykangaroo$', 'o$', 'oo$', 'roo$'," + " 'rykangaroo$', 'ykangaroo$']" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + f"(https://console.developers.google.com/)" + f"2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + f"4. In the list of APIs choose or search for YouTube Data API v3 and " + f"click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + f"6. Click on Create Credential at the top." + f'7. At the top click the link for "API key".' + f"8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{{prefix}}set api youtube api_key`" +) +message = ( + f"1. Go to Google Developers Console and log in with your Google account." + f"(https://console.developers.google.com/)" + f"2. You should be prompted to create a new project (name does not matter)." + f"3. Click on Enable APIs and Services at the top." + f"4. In the list of APIs choose or search for YouTube Data API v3 and " + f"click on it. Choose Enable." + f"5. Click on Credentials on the left navigation bar." + f"6. Click on Create Credential at the top." + f'7. At the top click the link for "API key".' + f"8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{{prefix}}set api youtube api_key`" +) +message = ( + "1. Go to Google Developers Console and log in with your Google account." + "(https://console.developers.google.com/)" + "2. You should be prompted to create a new project (name does not matter)." + "3. Click on Enable APIs and Services at the top." + "4. In the list of APIs choose or search for YouTube Data API v3 and " + "click on it. Choose Enable." + "5. Click on Credentials on the left navigation bar." + "6. Click on Create Credential at the top." + '7. At the top click the link for "API key".' + "8. No application restrictions are needed. Click Create at the bottom." + f"9. You now have a key to add to `{prefix}set api youtube api_key`" +) + +# It shouldn't matter if the string prefixes are capitalized. +temp_msg = ( + f"{F'{humanize_number(pos)}.': <{pound_len+2}} " + f"{balance: <{bal_len + 5}} " + f"<<{author.display_name}>>\n" +) + +fstring = f"We have to remember to escape {braces}. Like {{these}}. But not {this}." + +welcome_to_programming = R"hello," R" world!" + +fstring = ( + f"f-strings definitely make things more {difficult} than they need to be for" + " {black}. But boy they sure are handy. The problem is that some lines will need" + f" to have the 'f' whereas others do not. This {line}, for example, needs one." +) + +x = ( + "This is a long string which contains an f-expr that should not split" + f" {{{[i for i in range(5)]}}}." +) + +x = ( + "\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}\N{VARIATION SELECTOR-16}" +) + +xxxxxx_xxx_xxxx_xx_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxx_xxxx_xxxxx = xxxx.xxxxxx.xxxxxxxxx.xxxxxxxxxxxxxxxxxxxx( + xx_xxxxxx={ + "x3_xxxxxxxx": ( + "xxx3_xxxxx_xxxxxxxx_xxxxxxxx_xxxxxxxxxx_xxxxxxxx_xxxxxx_xxxxxxx" + ), + }, +) + +# Regression test for https://github.com/psf/black/issues/3117. +some_dict = { + "something_something": ( + r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" + r"signiferumque, duo ea vocibus consetetur scriptorem. Facer \t" + ), +} + +# Regression test for https://github.com/psf/black/issues/3459. +xxxx( + empty_str_as_first_split=( + "" + f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " + "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " + f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}" + ), + empty_u_str_as_first_split=( + "" + f"xxxxxxx {xxxxxxxxxx} xxx xxxxxxxxxx xxxxx xxx xxx xx " + "xxxxx xxxxxxxxx xxxxxxx, xxx xxxxxxxxxxx xxx xxxxx. " + f"xxxxxxxxxxxxx xxxx xx xxxxxxxxxx. xxxxx: {x.xxx}" + ), +) + +# Regression test for https://github.com/psf/black/issues/3455. +a_dict = { + "/this/is/a/very/very/very/very/very/very/very/very/very/very/long/key/without/spaces": + # And there is a comment before the value + ("item1", "item2", "item3"), +} + +# Regression test for https://github.com/psf/black/issues/3506. +s = f"With single quote: ' {my_dict['foo']} With double quote: \" {my_dict['bar']}" + +s = ( + "Lorem Ipsum is simply dummy text of the printing and typesetting" + f" industry:'{my_dict['foo']}'" +) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__type_annotations.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__type_annotations.py.snap new file mode 100644 index 0000000000000..8b8220f9c47cb --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_long_strings__type_annotations.py.snap @@ -0,0 +1,115 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_long_strings__type_annotations.py +--- +## Input + +```python +def func( + arg1, + arg2, +) -> Set["this_is_a_very_long_module_name.AndAVeryLongClasName" + ".WithAVeryVeryVeryVeryVeryLongSubClassName"]: + pass + + +def func( + argument: ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" + ), +) -> ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" +): + pass + + +def func( + argument: ( + "int |" + "str" + ), +) -> Set["int |" + " str"]: + pass +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -21,6 +21,6 @@ + + + def func( +- argument: "int |" "str", ++ argument: ("int |" "str"), + ) -> Set["int |" " str"]: + pass +``` + +## Ruff Output + +```python +def func( + arg1, + arg2, +) -> Set[ + "this_is_a_very_long_module_name.AndAVeryLongClasName" + ".WithAVeryVeryVeryVeryVeryLongSubClassName" +]: + pass + + +def func( + argument: ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" + ), +) -> ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" +): + pass + + +def func( + argument: ("int |" "str"), +) -> Set["int |" " str"]: + pass +``` + +## Black Output + +```python +def func( + arg1, + arg2, +) -> Set[ + "this_is_a_very_long_module_name.AndAVeryLongClasName" + ".WithAVeryVeryVeryVeryVeryLongSubClassName" +]: + pass + + +def func( + argument: ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" + ), +) -> ( + "VeryLongClassNameWithAwkwardGenericSubtype[int] |" + "VeryLongClassNameWithAwkwardGenericSubtype[str]" +): + pass + + +def func( + argument: "int |" "str", +) -> Set["int |" " str"]: + pass +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_multiline_strings.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_multiline_strings.py.snap new file mode 100644 index 0000000000000..9e841c8b21eee --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_multiline_strings.py.snap @@ -0,0 +1,923 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_multiline_strings.py +--- +## Input + +```python +"""cow +say""", +call(3, "dogsay", textwrap.dedent("""dove + coo""" % "cowabunga")) +call(3, "dogsay", textwrap.dedent("""dove +coo""" % "cowabunga")) +call(3, textwrap.dedent("""cow + moo""" % "cowabunga"), "dogsay") +call(3, "dogsay", textwrap.dedent("""crow + caw""" % "cowabunga"),) +call(3, textwrap.dedent("""cat + meow""" % "cowabunga"), {"dog", "say"}) +call(3, {"dog", "say"}, textwrap.dedent("""horse + neigh""" % "cowabunga")) +call(3, {"dog", "say"}, textwrap.dedent("""pig + oink""" % "cowabunga"),) +textwrap.dedent("""A one-line triple-quoted string.""") +textwrap.dedent("""A two-line triple-quoted string +since it goes to the next line.""") +textwrap.dedent("""A three-line triple-quoted string +that not only goes to the next line +but also goes one line beyond.""") +textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""") +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""")) +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {config_filename} file contents. +""".format("config_filename", config_filename))) +# Another use case +data = yaml.load("""\ +a: 1 +b: 2 +""") +data = yaml.load("""\ +a: 1 +b: 2 +""",) +data = yaml.load( + """\ + a: 1 + b: 2 +""" +) + +MULTILINE = """ +foo +""".replace("\n", "") +generated_readme = lambda project_name: """ +{} + + +""".strip().format(project_name) +parser.usage += """ +Custom extra help summary. + +Extra test: +- with +- bullets +""" + + +def get_stuff(cr, value): + # original + cr.execute(""" + SELECT whatever + FROM some_table t + WHERE id = %s + """, [value]) + return cr.fetchone() + + +def get_stuff(cr, value): + # preferred + cr.execute( + """ + SELECT whatever + FROM some_table t + WHERE id = %s + """, + [value], + ) + return cr.fetchone() + + +call(arg1, arg2, """ +short +""", arg3=True) +test_vectors = [ + "one-liner\n", + "two\nliner\n", + """expressed +as a three line +mulitline string""", +] + +_wat = re.compile( + r""" + regex + """, + re.MULTILINE | re.VERBOSE, +) +dis_c_instance_method = """\ +%3d 0 LOAD_FAST 1 (x) + 2 LOAD_CONST 1 (1) + 4 COMPARE_OP 2 (==) + 6 LOAD_FAST 0 (self) + 8 STORE_ATTR 0 (x) + 10 LOAD_CONST 0 (None) + 12 RETURN_VALUE +""" % (_C.__init__.__code__.co_firstlineno + 1,) +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually {verb} the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {file_type} file contents. +""".format(verb="using", file_type="test"))) +{"""cow +moos"""} +["""cow +moos"""] +["""cow +moos""", """dog +woofs +and +barks"""] +def dastardly_default_value( + cow: String = json.loads("""this +is +quite +the +dastadardly +value!"""), + **kwargs, +): + pass + +print(f""" + This {animal} + moos and barks +{animal} say +""") +msg = f"""The arguments {bad_arguments} were passed in. +Please use `--build-option` instead, +`--global-option` is reserved to flags like `--verbose` or `--quiet`. +""" + +this_will_become_one_line = ( + "a" + "b" + "c" +) + +this_will_stay_on_three_lines = ( + "a" # comment + "b" + "c" +) + +this_will_also_become_one_line = ( # comment + "a" + "b" + "c" +) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,95 +1,138 @@ +-"""cow ++( ++ """cow + say""", ++) + call( + 3, + "dogsay", +- textwrap.dedent("""dove +- coo""" % "cowabunga"), ++ textwrap.dedent( ++ """dove ++ coo""" ++ % "cowabunga" ++ ), + ) + call( + 3, + "dogsay", +- textwrap.dedent("""dove +-coo""" % "cowabunga"), ++ textwrap.dedent( ++ """dove ++coo""" ++ % "cowabunga" ++ ), + ) + call( + 3, +- textwrap.dedent("""cow +- moo""" % "cowabunga"), ++ textwrap.dedent( ++ """cow ++ moo""" ++ % "cowabunga" ++ ), + "dogsay", + ) + call( + 3, + "dogsay", +- textwrap.dedent("""crow +- caw""" % "cowabunga"), ++ textwrap.dedent( ++ """crow ++ caw""" ++ % "cowabunga" ++ ), + ) + call( + 3, +- textwrap.dedent("""cat +- meow""" % "cowabunga"), ++ textwrap.dedent( ++ """cat ++ meow""" ++ % "cowabunga" ++ ), + {"dog", "say"}, + ) + call( + 3, + {"dog", "say"}, +- textwrap.dedent("""horse +- neigh""" % "cowabunga"), ++ textwrap.dedent( ++ """horse ++ neigh""" ++ % "cowabunga" ++ ), + ) + call( + 3, + {"dog", "say"}, +- textwrap.dedent("""pig +- oink""" % "cowabunga"), ++ textwrap.dedent( ++ """pig ++ oink""" ++ % "cowabunga" ++ ), + ) + textwrap.dedent("""A one-line triple-quoted string.""") +-textwrap.dedent("""A two-line triple-quoted string +-since it goes to the next line.""") +-textwrap.dedent("""A three-line triple-quoted string ++textwrap.dedent( ++ """A two-line triple-quoted string ++since it goes to the next line.""" ++) ++textwrap.dedent( ++ """A three-line triple-quoted string + that not only goes to the next line +-but also goes one line beyond.""") +-textwrap.dedent("""\ ++but also goes one line beyond.""" ++) ++textwrap.dedent( ++ """\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +-""") +-path.write_text(textwrap.dedent("""\ ++""" ++) ++path.write_text( ++ textwrap.dedent( ++ """\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +-""")) +-path.write_text(textwrap.dedent("""\ ++""" ++ ) ++) ++path.write_text( ++ textwrap.dedent( ++ """\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {config_filename} file contents. +-""".format("config_filename", config_filename))) ++""".format("config_filename", config_filename) ++ ) ++) + # Another use case +-data = yaml.load("""\ ++data = yaml.load( ++ """\ + a: 1 + b: 2 +-""") ++""" ++) + data = yaml.load( + """\ + a: 1 + b: 2 + """, + ) +-data = yaml.load("""\ ++data = yaml.load( ++ """\ + a: 1 + b: 2 +-""") ++""" ++) + + MULTILINE = """ + foo + """.replace("\n", "") +-generated_readme = lambda project_name: """ ++generated_readme = ( ++ lambda project_name: """ + {} + + + """.strip().format(project_name) ++) + parser.usage += """ + Custom extra help summary. + +@@ -156,16 +199,24 @@ + 10 LOAD_CONST 0 (None) + 12 RETURN_VALUE + """ % (_C.__init__.__code__.co_firstlineno + 1,) +-path.write_text(textwrap.dedent("""\ ++path.write_text( ++ textwrap.dedent( ++ """\ + A triple-quoted string + actually {verb} the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {file_type} file contents. +-""".format(verb="using", file_type="test"))) +-{"""cow +-moos"""} +-["""cow +-moos"""] ++""".format(verb="using", file_type="test") ++ ) ++) ++{ ++ """cow ++moos""" ++} ++[ ++ """cow ++moos""" ++] + [ + """cow + moos""", +@@ -177,28 +228,32 @@ + + + def dastardly_default_value( +- cow: String = json.loads("""this ++ cow: String = json.loads( ++ """this + is + quite + the + dastadardly +-value!"""), ++value!""" ++ ), + **kwargs, + ): + pass + + +-print(f""" ++print( ++ f""" + This {animal} + moos and barks + {animal} say +-""") ++""" ++) + msg = f"""The arguments {bad_arguments} were passed in. + Please use `--build-option` instead, + `--global-option` is reserved to flags like `--verbose` or `--quiet`. + """ + +-this_will_become_one_line = "abc" ++this_will_become_one_line = "a" "b" "c" + + this_will_stay_on_three_lines = ( + "a" # comment +@@ -206,4 +261,6 @@ + "c" + ) + +-this_will_also_become_one_line = "abc" # comment ++this_will_also_become_one_line = ( # comment ++ "a" "b" "c" ++) +``` + +## Ruff Output + +```python +( + """cow +say""", +) +call( + 3, + "dogsay", + textwrap.dedent( + """dove + coo""" + % "cowabunga" + ), +) +call( + 3, + "dogsay", + textwrap.dedent( + """dove +coo""" + % "cowabunga" + ), +) +call( + 3, + textwrap.dedent( + """cow + moo""" + % "cowabunga" + ), + "dogsay", +) +call( + 3, + "dogsay", + textwrap.dedent( + """crow + caw""" + % "cowabunga" + ), +) +call( + 3, + textwrap.dedent( + """cat + meow""" + % "cowabunga" + ), + {"dog", "say"}, +) +call( + 3, + {"dog", "say"}, + textwrap.dedent( + """horse + neigh""" + % "cowabunga" + ), +) +call( + 3, + {"dog", "say"}, + textwrap.dedent( + """pig + oink""" + % "cowabunga" + ), +) +textwrap.dedent("""A one-line triple-quoted string.""") +textwrap.dedent( + """A two-line triple-quoted string +since it goes to the next line.""" +) +textwrap.dedent( + """A three-line triple-quoted string +that not only goes to the next line +but also goes one line beyond.""" +) +textwrap.dedent( + """\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""" +) +path.write_text( + textwrap.dedent( + """\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""" + ) +) +path.write_text( + textwrap.dedent( + """\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {config_filename} file contents. +""".format("config_filename", config_filename) + ) +) +# Another use case +data = yaml.load( + """\ +a: 1 +b: 2 +""" +) +data = yaml.load( + """\ +a: 1 +b: 2 +""", +) +data = yaml.load( + """\ + a: 1 + b: 2 +""" +) + +MULTILINE = """ +foo +""".replace("\n", "") +generated_readme = ( + lambda project_name: """ +{} + + +""".strip().format(project_name) +) +parser.usage += """ +Custom extra help summary. + +Extra test: +- with +- bullets +""" + + +def get_stuff(cr, value): + # original + cr.execute( + """ + SELECT whatever + FROM some_table t + WHERE id = %s + """, + [value], + ) + return cr.fetchone() + + +def get_stuff(cr, value): + # preferred + cr.execute( + """ + SELECT whatever + FROM some_table t + WHERE id = %s + """, + [value], + ) + return cr.fetchone() + + +call( + arg1, + arg2, + """ +short +""", + arg3=True, +) +test_vectors = [ + "one-liner\n", + "two\nliner\n", + """expressed +as a three line +mulitline string""", +] + +_wat = re.compile( + r""" + regex + """, + re.MULTILINE | re.VERBOSE, +) +dis_c_instance_method = """\ +%3d 0 LOAD_FAST 1 (x) + 2 LOAD_CONST 1 (1) + 4 COMPARE_OP 2 (==) + 6 LOAD_FAST 0 (self) + 8 STORE_ATTR 0 (x) + 10 LOAD_CONST 0 (None) + 12 RETURN_VALUE +""" % (_C.__init__.__code__.co_firstlineno + 1,) +path.write_text( + textwrap.dedent( + """\ + A triple-quoted string + actually {verb} the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {file_type} file contents. +""".format(verb="using", file_type="test") + ) +) +{ + """cow +moos""" +} +[ + """cow +moos""" +] +[ + """cow +moos""", + """dog +woofs +and +barks""", +] + + +def dastardly_default_value( + cow: String = json.loads( + """this +is +quite +the +dastadardly +value!""" + ), + **kwargs, +): + pass + + +print( + f""" + This {animal} + moos and barks +{animal} say +""" +) +msg = f"""The arguments {bad_arguments} were passed in. +Please use `--build-option` instead, +`--global-option` is reserved to flags like `--verbose` or `--quiet`. +""" + +this_will_become_one_line = "a" "b" "c" + +this_will_stay_on_three_lines = ( + "a" # comment + "b" + "c" +) + +this_will_also_become_one_line = ( # comment + "a" "b" "c" +) +``` + +## Black Output + +```python +"""cow +say""", +call( + 3, + "dogsay", + textwrap.dedent("""dove + coo""" % "cowabunga"), +) +call( + 3, + "dogsay", + textwrap.dedent("""dove +coo""" % "cowabunga"), +) +call( + 3, + textwrap.dedent("""cow + moo""" % "cowabunga"), + "dogsay", +) +call( + 3, + "dogsay", + textwrap.dedent("""crow + caw""" % "cowabunga"), +) +call( + 3, + textwrap.dedent("""cat + meow""" % "cowabunga"), + {"dog", "say"}, +) +call( + 3, + {"dog", "say"}, + textwrap.dedent("""horse + neigh""" % "cowabunga"), +) +call( + 3, + {"dog", "say"}, + textwrap.dedent("""pig + oink""" % "cowabunga"), +) +textwrap.dedent("""A one-line triple-quoted string.""") +textwrap.dedent("""A two-line triple-quoted string +since it goes to the next line.""") +textwrap.dedent("""A three-line triple-quoted string +that not only goes to the next line +but also goes one line beyond.""") +textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""") +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. file contents. +""")) +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually leveraging the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {config_filename} file contents. +""".format("config_filename", config_filename))) +# Another use case +data = yaml.load("""\ +a: 1 +b: 2 +""") +data = yaml.load( + """\ +a: 1 +b: 2 +""", +) +data = yaml.load("""\ + a: 1 + b: 2 +""") + +MULTILINE = """ +foo +""".replace("\n", "") +generated_readme = lambda project_name: """ +{} + + +""".strip().format(project_name) +parser.usage += """ +Custom extra help summary. + +Extra test: +- with +- bullets +""" + + +def get_stuff(cr, value): + # original + cr.execute( + """ + SELECT whatever + FROM some_table t + WHERE id = %s + """, + [value], + ) + return cr.fetchone() + + +def get_stuff(cr, value): + # preferred + cr.execute( + """ + SELECT whatever + FROM some_table t + WHERE id = %s + """, + [value], + ) + return cr.fetchone() + + +call( + arg1, + arg2, + """ +short +""", + arg3=True, +) +test_vectors = [ + "one-liner\n", + "two\nliner\n", + """expressed +as a three line +mulitline string""", +] + +_wat = re.compile( + r""" + regex + """, + re.MULTILINE | re.VERBOSE, +) +dis_c_instance_method = """\ +%3d 0 LOAD_FAST 1 (x) + 2 LOAD_CONST 1 (1) + 4 COMPARE_OP 2 (==) + 6 LOAD_FAST 0 (self) + 8 STORE_ATTR 0 (x) + 10 LOAD_CONST 0 (None) + 12 RETURN_VALUE +""" % (_C.__init__.__code__.co_firstlineno + 1,) +path.write_text(textwrap.dedent("""\ + A triple-quoted string + actually {verb} the textwrap.dedent functionality + that ends in a trailing newline, + representing e.g. {file_type} file contents. +""".format(verb="using", file_type="test"))) +{"""cow +moos"""} +["""cow +moos"""] +[ + """cow +moos""", + """dog +woofs +and +barks""", +] + + +def dastardly_default_value( + cow: String = json.loads("""this +is +quite +the +dastadardly +value!"""), + **kwargs, +): + pass + + +print(f""" + This {animal} + moos and barks +{animal} say +""") +msg = f"""The arguments {bad_arguments} were passed in. +Please use `--build-option` instead, +`--global-option` is reserved to flags like `--verbose` or `--quiet`. +""" + +this_will_become_one_line = "abc" + +this_will_stay_on_three_lines = ( + "a" # comment + "b" + "c" +) + +this_will_also_become_one_line = "abc" # comment +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_no_blank_line_before_docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_no_blank_line_before_docstring.py.snap new file mode 100644 index 0000000000000..bd93e24292838 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_no_blank_line_before_docstring.py.snap @@ -0,0 +1,134 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_no_blank_line_before_docstring.py +--- +## Input + +```python +def line_before_docstring(): + + """Please move me up""" + + +class LineBeforeDocstring: + + """Please move me up""" + + +class EvenIfThereIsAMethodAfter: + + """I'm the docstring""" + def method(self): + pass + + +class TwoLinesBeforeDocstring: + + + """I want to be treated the same as if I were closer""" + + +class MultilineDocstringsAsWell: + + """I'm so far + + and on so many lines... + """ +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -3,10 +3,12 @@ + + + class LineBeforeDocstring: ++ + """Please move me up""" + + + class EvenIfThereIsAMethodAfter: ++ + """I'm the docstring""" + + def method(self): +@@ -14,10 +16,12 @@ + + + class TwoLinesBeforeDocstring: ++ + """I want to be treated the same as if I were closer""" + + + class MultilineDocstringsAsWell: ++ + """I'm so far + + and on so many lines... +``` + +## Ruff Output + +```python +def line_before_docstring(): + """Please move me up""" + + +class LineBeforeDocstring: + + """Please move me up""" + + +class EvenIfThereIsAMethodAfter: + + """I'm the docstring""" + + def method(self): + pass + + +class TwoLinesBeforeDocstring: + + """I want to be treated the same as if I were closer""" + + +class MultilineDocstringsAsWell: + + """I'm so far + + and on so many lines... + """ +``` + +## Black Output + +```python +def line_before_docstring(): + """Please move me up""" + + +class LineBeforeDocstring: + """Please move me up""" + + +class EvenIfThereIsAMethodAfter: + """I'm the docstring""" + + def method(self): + pass + + +class TwoLinesBeforeDocstring: + """I want to be treated the same as if I were closer""" + + +class MultilineDocstringsAsWell: + """I'm so far + + and on so many lines... + """ +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_pattern_matching_trailing_comma.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_pattern_matching_trailing_comma.py.snap new file mode 100644 index 0000000000000..257d3e63f6003 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_pattern_matching_trailing_comma.py.snap @@ -0,0 +1,104 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pattern_matching_trailing_comma.py +--- +## Input + +```python +match maybe, multiple: + case perhaps, 5: + pass + case perhaps, 6,: + pass + + +match more := (than, one), indeed,: + case _, (5, 6): + pass + case [[5], (6)], [7],: + pass + case _: + pass +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -8,13 +8,16 @@ + pass + + +-match more := (than, one), indeed,: ++match ( ++ more := (than, one), ++ indeed, ++): + case _, (5, 6): + pass +- case ( ++ case [ + [[5], (6)], + [7], +- ): ++ ]: + pass + case _: + pass +``` + +## Ruff Output + +```python +match maybe, multiple: + case perhaps, 5: + pass + case ( + perhaps, + 6, + ): + pass + + +match ( + more := (than, one), + indeed, +): + case _, (5, 6): + pass + case [ + [[5], (6)], + [7], + ]: + pass + case _: + pass +``` + +## Black Output + +```python +match maybe, multiple: + case perhaps, 5: + pass + case ( + perhaps, + 6, + ): + pass + + +match more := (than, one), indeed,: + case _, (5, 6): + pass + case ( + [[5], (6)], + [7], + ): + pass + case _: + pass +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_pep_572.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_pep_572.py.snap new file mode 100644 index 0000000000000..03f27f16c2f35 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_pep_572.py.snap @@ -0,0 +1,38 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_pep_572.py +--- +## Input + +```python +x[(a:=0):] +x[:(a:=0)] +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,2 +1,2 @@ +-x[(a := 0):] +-x[:(a := 0)] ++x[(a := 0) :] ++x[: (a := 0)] +``` + +## Ruff Output + +```python +x[(a := 0) :] +x[: (a := 0)] +``` + +## Black Output + +```python +x[(a := 0):] +x[:(a := 0)] +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_percent_precedence.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_percent_precedence.py.snap new file mode 100644 index 0000000000000..01f401e99a11a --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_percent_precedence.py.snap @@ -0,0 +1,99 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_percent_precedence.py +--- +## Input + +```python +("" % a) ** 2 +("" % a)[0] +("" % a)() +("" % a).b + +2 * ("" % a) +2 @ ("" % a) +2 / ("" % a) +2 // ("" % a) +2 % ("" % a) ++("" % a) +b + ("" % a) +-("" % a) +b - ("" % a) +b + -("" % a) +~("" % a) +2 ** ("" % a) +await ("" % a) +b[("" % a)] +b(("" % a)) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -9,9 +9,9 @@ + 2 // ("" % a) + 2 % ("" % a) + +("" % a) +-b + "" % a ++b + ("" % a) + -("" % a) +-b - "" % a ++b - ("" % a) + b + -("" % a) + ~("" % a) + 2 ** ("" % a) +``` + +## Ruff Output + +```python +("" % a) ** 2 +("" % a)[0] +("" % a)() +("" % a).b + +2 * ("" % a) +2 @ ("" % a) +2 / ("" % a) +2 // ("" % a) +2 % ("" % a) ++("" % a) +b + ("" % a) +-("" % a) +b - ("" % a) +b + -("" % a) +~("" % a) +2 ** ("" % a) +await ("" % a) +b[("" % a)] +b(("" % a)) +``` + +## Black Output + +```python +("" % a) ** 2 +("" % a)[0] +("" % a)() +("" % a).b + +2 * ("" % a) +2 @ ("" % a) +2 / ("" % a) +2 // ("" % a) +2 % ("" % a) ++("" % a) +b + "" % a +-("" % a) +b - "" % a +b + -("" % a) +~("" % a) +2 ** ("" % a) +await ("" % a) +b[("" % a)] +b(("" % a)) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_prefer_rhs_split.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_prefer_rhs_split.py.snap new file mode 100644 index 0000000000000..e799efc3145f6 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_prefer_rhs_split.py.snap @@ -0,0 +1,354 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_prefer_rhs_split.py +--- +## Input + +```python +first_item, second_item = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure it works when the RHS only has one pair of (optional) parens. +first_item, second_item = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +# Make sure chaining assignments work. +first_item, second_item, third_item, forth_item = m["everything"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure when the RHS's first split at the non-optional paren fits, +# we split there instead of the outer RHS optional paren. +first_item, second_item = some_looooooooong_module.some_loooooog_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = everything = some_looooong_function_name( + first_argument, second_argument, third_argument +) + + +# Make sure unsplittable type ignore won't be moved. +some_kind_of_table[some_key] = util.some_function( # type: ignore # noqa: E501 + some_arg +).intersection(pk_cols) + +some_kind_of_table[ + some_key +] = lambda obj: obj.some_long_named_method() # type: ignore # noqa: E501 + +some_kind_of_table[ + some_key # type: ignore # noqa: E501 +] = lambda obj: obj.some_long_named_method() + + +# Make when when the left side of assignment plus the opening paren "... = (" is +# exactly line length limit + 1, it won't be split like that. +xxxxxxxxx_yyy_zzzzzzzz[ + xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1) +] = 1 + + +# Right side of assignment contains un-nested pairs of inner parens. +some_kind_of_instance.some_kind_of_map[a_key] = ( + isinstance(some_var, SomeClass) + and table.something_and_something != table.something_else +) or ( + isinstance(some_other_var, BaseClass) and table.something != table.some_other_thing +) + +# Multiple targets +a = b = ( + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) + +a = b = c = d = e = f = g = ( + hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +) = i = j = ( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk +) + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = c + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = ( + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) = ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -60,9 +60,7 @@ + some_arg + ).intersection(pk_cols) + +-some_kind_of_table[ +- some_key +-] = lambda obj: obj.some_long_named_method() # type: ignore # noqa: E501 ++some_kind_of_table[some_key] = lambda obj: obj.some_long_named_method() # type: ignore # noqa: E501 + + some_kind_of_table[ + some_key # type: ignore # noqa: E501 +``` + +## Ruff Output + +```python +first_item, second_item = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure it works when the RHS only has one pair of (optional) parens. +first_item, second_item = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +# Make sure chaining assignments work. +first_item, second_item, third_item, forth_item = m["everything"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure when the RHS's first split at the non-optional paren fits, +# we split there instead of the outer RHS optional paren. +first_item, second_item = some_looooooooong_module.some_loooooog_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = everything = some_looooong_function_name( + first_argument, second_argument, third_argument +) + + +# Make sure unsplittable type ignore won't be moved. +some_kind_of_table[some_key] = util.some_function( # type: ignore # noqa: E501 + some_arg +).intersection(pk_cols) + +some_kind_of_table[some_key] = lambda obj: obj.some_long_named_method() # type: ignore # noqa: E501 + +some_kind_of_table[ + some_key # type: ignore # noqa: E501 +] = lambda obj: obj.some_long_named_method() + + +# Make when when the left side of assignment plus the opening paren "... = (" is +# exactly line length limit + 1, it won't be split like that. +xxxxxxxxx_yyy_zzzzzzzz[ + xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1) +] = 1 + + +# Right side of assignment contains un-nested pairs of inner parens. +some_kind_of_instance.some_kind_of_map[a_key] = ( + isinstance(some_var, SomeClass) + and table.something_and_something != table.something_else +) or ( + isinstance(some_other_var, BaseClass) and table.something != table.some_other_thing +) + +# Multiple targets +a = b = ( + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) + +a = b = c = d = e = f = g = ( + hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +) = i = j = ( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk +) + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = c + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = ( + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) = ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd +``` + +## Black Output + +```python +first_item, second_item = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure it works when the RHS only has one pair of (optional) parens. +first_item, second_item = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +some_dict["with_a_long_key"] = ( + some_looooooooong_module.SomeClass.some_looooooooooooooong_variable_name +) + +# Make sure chaining assignments work. +first_item, second_item, third_item, forth_item = m["everything"] = ( + some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument + ) +) + +# Make sure when the RHS's first split at the non-optional paren fits, +# we split there instead of the outer RHS optional paren. +first_item, second_item = some_looooooooong_module.some_loooooog_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = some_looooooooong_module.some_looooooooooooooong_function_name( + first_argument, second_argument, third_argument +) + +( + first_item, + second_item, + third_item, + forth_item, + fifth_item, + last_item_very_loooooong, +) = everything = some_looooong_function_name( + first_argument, second_argument, third_argument +) + + +# Make sure unsplittable type ignore won't be moved. +some_kind_of_table[some_key] = util.some_function( # type: ignore # noqa: E501 + some_arg +).intersection(pk_cols) + +some_kind_of_table[ + some_key +] = lambda obj: obj.some_long_named_method() # type: ignore # noqa: E501 + +some_kind_of_table[ + some_key # type: ignore # noqa: E501 +] = lambda obj: obj.some_long_named_method() + + +# Make when when the left side of assignment plus the opening paren "... = (" is +# exactly line length limit + 1, it won't be split like that. +xxxxxxxxx_yyy_zzzzzzzz[ + xx.xxxxxx(x_yyy_zzzzzz.xxxxx[0]), x_yyy_zzzzzz.xxxxxx(xxxx=1) +] = 1 + + +# Right side of assignment contains un-nested pairs of inner parens. +some_kind_of_instance.some_kind_of_map[a_key] = ( + isinstance(some_var, SomeClass) + and table.something_and_something != table.something_else +) or ( + isinstance(some_other_var, BaseClass) and table.something != table.some_other_thing +) + +# Multiple targets +a = b = ( + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) + +a = b = c = d = e = f = g = ( + hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh +) = i = j = ( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk +) + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = c + +a = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = ( + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +) = ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_return_annotation_brackets_string.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_return_annotation_brackets_string.py.snap new file mode 100644 index 0000000000000..5f43f1a7d20b5 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_return_annotation_brackets_string.py.snap @@ -0,0 +1,68 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_return_annotation_brackets_string.py +--- +## Input + +```python +# Long string example +def frobnicate() -> "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]": + pass + +# splitting the string breaks if there's any parameters +def frobnicate(a) -> "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]": + pass +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,7 +1,6 @@ + # Long string example + def frobnicate() -> ( +- "ThisIsTrulyUnreasonablyExtremelyLongClassName |" +- " list[ThisIsTrulyUnreasonablyExtremelyLongClassName]" ++ "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]" + ): + pass + +``` + +## Ruff Output + +```python +# Long string example +def frobnicate() -> ( + "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]" +): + pass + + +# splitting the string breaks if there's any parameters +def frobnicate( + a, +) -> "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]": + pass +``` + +## Black Output + +```python +# Long string example +def frobnicate() -> ( + "ThisIsTrulyUnreasonablyExtremelyLongClassName |" + " list[ThisIsTrulyUnreasonablyExtremelyLongClassName]" +): + pass + + +# splitting the string breaks if there's any parameters +def frobnicate( + a, +) -> "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]": + pass +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_single_line_format_skip_with_multiple_comments.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_single_line_format_skip_with_multiple_comments.py.snap new file mode 100644 index 0000000000000..78dc5bad0d197 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__preview_single_line_format_skip_with_multiple_comments.py.snap @@ -0,0 +1,64 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/preview_single_line_format_skip_with_multiple_comments.py +--- +## Input + +```python +foo = 123 # fmt: skip # noqa: E501 # pylint +bar = ( + 123 , + ( 1 + 5 ) # pylint # fmt:skip +) +baz = "a" + "b" # pylint; fmt: skip; noqa: E501 +skip_will_not_work = "a" + "b" # pylint fmt:skip +skip_will_not_work2 = "a" + "b" # some text; fmt:skip happens to be part of it +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,8 +1,8 @@ +-foo = 123 # fmt: skip # noqa: E501 # pylint ++foo = 123 # fmt: skip # noqa: E501 # pylint + bar = ( +- 123 , +- ( 1 + 5 ) # pylint # fmt:skip ++ 123, ++ (1 + 5), # pylint # fmt:skip + ) +-baz = "a" + "b" # pylint; fmt: skip; noqa: E501 ++baz = "a" + "b" # pylint; fmt: skip; noqa: E501 + skip_will_not_work = "a" + "b" # pylint fmt:skip + skip_will_not_work2 = "a" + "b" # some text; fmt:skip happens to be part of it +``` + +## Ruff Output + +```python +foo = 123 # fmt: skip # noqa: E501 # pylint +bar = ( + 123, + (1 + 5), # pylint # fmt:skip +) +baz = "a" + "b" # pylint; fmt: skip; noqa: E501 +skip_will_not_work = "a" + "b" # pylint fmt:skip +skip_will_not_work2 = "a" + "b" # some text; fmt:skip happens to be part of it +``` + +## Black Output + +```python +foo = 123 # fmt: skip # noqa: E501 # pylint +bar = ( + 123 , + ( 1 + 5 ) # pylint # fmt:skip +) +baz = "a" + "b" # pylint; fmt: skip; noqa: E501 +skip_will_not_work = "a" + "b" # pylint fmt:skip +skip_will_not_work2 = "a" + "b" # some text; fmt:skip happens to be part of it +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__raw_docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__raw_docstring.py.snap new file mode 100644 index 0000000000000..8b27585265471 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__raw_docstring.py.snap @@ -0,0 +1,89 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/raw_docstring.py +--- +## Input + +```python +class C: + + r"""Raw""" + +def f(): + + r"""Raw""" + +class SingleQuotes: + + + r'''Raw''' + +class UpperCaseR: + R"""Raw""" +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,4 +1,5 @@ + class C: ++ + r"""Raw""" + + +@@ -7,8 +8,9 @@ + + + class SingleQuotes: +- r'''Raw''' + ++ r"""Raw""" ++ + + class UpperCaseR: + R"""Raw""" +``` + +## Ruff Output + +```python +class C: + + r"""Raw""" + + +def f(): + r"""Raw""" + + +class SingleQuotes: + + r"""Raw""" + + +class UpperCaseR: + R"""Raw""" +``` + +## Black Output + +```python +class C: + r"""Raw""" + + +def f(): + r"""Raw""" + + +class SingleQuotes: + r'''Raw''' + + +class UpperCaseR: + R"""Raw""" +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_await_parens.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_await_parens.py.snap similarity index 90% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_await_parens.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_await_parens.py.snap index 33eabc6fa9b93..284e85189ee12 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_await_parens.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_await_parens.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_await_parens.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_await_parens.py --- ## Input @@ -86,6 +86,15 @@ async def main(): async def main(): await (yield) + +async def main(): + await (a ** b) + await (a[b] ** c) + await (a ** b[c]) + await ((a + b) ** (c + d)) + await (a + b) + await (a[b]) + await (a[b ** c]) ``` ## Black Differences @@ -213,6 +222,16 @@ async def main(): async def main(): await (yield) + + +async def main(): + await (a**b) + await (a[b] ** c) + await (a ** b[c]) + await ((a + b) ** (c + d)) + await (a + b) + await a[b] + await a[b**c] ``` ## Black Output @@ -311,6 +330,16 @@ async def main(): async def main(): await (yield) + + +async def main(): + await (a**b) + await (a[b] ** c) + await (a ** b[c]) + await ((a + b) ** (c + d)) + await (a + b) + await a[b] + await a[b**c] ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_except_parens.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_except_parens.py.snap similarity index 98% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_except_parens.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_except_parens.py.snap index a0459420e5ce4..55f1e953849c3 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_except_parens.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_except_parens.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_except_parens.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_except_parens.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_for_brackets.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_for_brackets.py.snap similarity index 98% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_for_brackets.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_for_brackets.py.snap index 3c2eb7eab684e..5b98ee4d7f870 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_for_brackets.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__remove_for_brackets.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/remove_for_brackets.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/remove_for_brackets.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__return_annotation_brackets.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__return_annotation_brackets.py.snap similarity index 90% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__return_annotation_brackets.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__return_annotation_brackets.py.snap index fd67777f13055..9bf6a451152c9 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__return_annotation_brackets.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__return_annotation_brackets.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/return_annotation_brackets.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/return_annotation_brackets.py --- ## Input @@ -93,6 +93,11 @@ def foo() -> tuple[loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo # Magic trailing comma example def foo() -> tuple[int, int, int,]: return 2 + +# Magic trailing comma example, with params +# this is broken - the trailing comma is transferred to the param list. Fixed in preview +def foo(a,b) -> tuple[int, int, int,]: + return 2 ``` ## Black Differences @@ -106,7 +111,7 @@ def foo() -> tuple[int, int, int,]: # Don't lose the comments -def double(a: int) -> int: # Hello +def double( -+ a: int ++ a: int, +) -> ( # Hello + int +): @@ -115,13 +120,24 @@ def foo() -> tuple[int, int, int,]: -def double(a: int) -> int: # Hello +def double( -+ a: int ++ a: int, +) -> ( + int # Hello +): return 2 * a +@@ -124,5 +132,9 @@ + # this is broken - the trailing comma is transferred to the param list. Fixed in preview + def foo( + a, b +-) -> tuple[int, int, int,]: ++) -> tuple[ ++ int, ++ int, ++ int, ++]: + return 2 ``` ## Ruff Output @@ -152,7 +168,7 @@ def double(a: int) -> int: # Don't lose the comments def double( - a: int + a: int, ) -> ( # Hello int ): @@ -160,7 +176,7 @@ def double( def double( - a: int + a: int, ) -> ( int # Hello ): @@ -255,6 +271,18 @@ def foo() -> ( ] ): return 2 + + +# Magic trailing comma example, with params +# this is broken - the trailing comma is transferred to the param list. Fixed in preview +def foo( + a, b +) -> tuple[ + int, + int, + int, +]: + return 2 ``` ## Black Output @@ -380,6 +408,14 @@ def foo() -> ( ] ): return 2 + + +# Magic trailing comma example, with params +# this is broken - the trailing comma is transferred to the param list. Fixed in preview +def foo( + a, b +) -> tuple[int, int, int,]: + return 2 ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__stub.pyi.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__stub.pyi.snap new file mode 100644 index 0000000000000..14b894cda7a0d --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__stub.pyi.snap @@ -0,0 +1,288 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/stub.pyi +--- +## Input + +```python +X: int + +def f(): ... + + +class D: + ... + + +class C: + ... + +class B: + this_lack_of_newline_should_be_kept: int + def b(self) -> None: ... + + but_this_newline_should_also_be_kept: int + +class A: + attr: int + attr2: str + + def f(self) -> int: + ... + + def g(self) -> str: ... + + + +def g(): + ... + +def h(): ... + +if sys.version_info >= (3, 8): + class E: + def f(self): ... + class F: + + def f(self): ... + class G: ... + class H: ... +else: + class I: ... + class J: ... + def f(): ... + + class K: + def f(self): ... + def f(): ... + +class Nested: + class dirty: ... + class little: ... + class secret: + def who_has_to_know(self): ... + def verse(self): ... + +class Conditional: + def f(self): ... + if sys.version_info >= (3, 8): + def g(self): ... + else: + def g(self): ... + def h(self): ... + def i(self): ... + if sys.version_info >= (3, 8): + def j(self): ... + def k(self): ... + if sys.version_info >= (3, 8): + class A: ... + class B: ... + class C: + def l(self): ... + def m(self): ... +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -24,31 +24,24 @@ + if sys.version_info >= (3, 8): + class E: + def f(self): ... +- + class F: + def f(self): ... +- + class G: ... + class H: ... +- + else: + class I: ... + class J: ... +- + def f(): ... + + class K: + def f(self): ... +- + def f(): ... + + class Nested: + class dirty: ... + class little: ... +- + class secret: + def who_has_to_know(self): ... +- + def verse(self): ... + + class Conditional: +@@ -57,17 +50,14 @@ + def g(self): ... + else: + def g(self): ... +- + def h(self): ... + def i(self): ... + if sys.version_info >= (3, 8): + def j(self): ... +- + def k(self): ... + if sys.version_info >= (3, 8): + class A: ... + class B: ... +- + class C: + def l(self): ... + def m(self): ... +``` + +## Ruff Output + +```python +X: int + +def f(): ... + +class D: ... +class C: ... + +class B: + this_lack_of_newline_should_be_kept: int + def b(self) -> None: ... + + but_this_newline_should_also_be_kept: int + +class A: + attr: int + attr2: str + + def f(self) -> int: ... + def g(self) -> str: ... + +def g(): ... +def h(): ... + +if sys.version_info >= (3, 8): + class E: + def f(self): ... + class F: + def f(self): ... + class G: ... + class H: ... +else: + class I: ... + class J: ... + def f(): ... + + class K: + def f(self): ... + def f(): ... + +class Nested: + class dirty: ... + class little: ... + class secret: + def who_has_to_know(self): ... + def verse(self): ... + +class Conditional: + def f(self): ... + if sys.version_info >= (3, 8): + def g(self): ... + else: + def g(self): ... + def h(self): ... + def i(self): ... + if sys.version_info >= (3, 8): + def j(self): ... + def k(self): ... + if sys.version_info >= (3, 8): + class A: ... + class B: ... + class C: + def l(self): ... + def m(self): ... +``` + +## Black Output + +```python +X: int + +def f(): ... + +class D: ... +class C: ... + +class B: + this_lack_of_newline_should_be_kept: int + def b(self) -> None: ... + + but_this_newline_should_also_be_kept: int + +class A: + attr: int + attr2: str + + def f(self) -> int: ... + def g(self) -> str: ... + +def g(): ... +def h(): ... + +if sys.version_info >= (3, 8): + class E: + def f(self): ... + + class F: + def f(self): ... + + class G: ... + class H: ... + +else: + class I: ... + class J: ... + + def f(): ... + + class K: + def f(self): ... + + def f(): ... + +class Nested: + class dirty: ... + class little: ... + + class secret: + def who_has_to_know(self): ... + + def verse(self): ... + +class Conditional: + def f(self): ... + if sys.version_info >= (3, 8): + def g(self): ... + else: + def g(self): ... + + def h(self): ... + def i(self): ... + if sys.version_info >= (3, 8): + def j(self): ... + + def k(self): ... + if sys.version_info >= (3, 8): + class A: ... + class B: ... + + class C: + def l(self): ... + def m(self): ... +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__torture.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__torture.py.snap similarity index 99% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__torture.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__torture.py.snap index 6b7ddaa378e9e..f8e78b1ac0e15 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__torture.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__torture.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/torture.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/torture.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__trailing_commas_in_leading_parts.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__trailing_commas_in_leading_parts.py.snap similarity index 98% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__trailing_commas_in_leading_parts.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__trailing_commas_in_leading_parts.py.snap index 8ad0695b0401c..fd4942632e8a3 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__trailing_commas_in_leading_parts.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__trailing_commas_in_leading_parts.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/trailing_commas_in_leading_parts.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/trailing_commas_in_leading_parts.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__tupleassign.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__tupleassign.py.snap similarity index 97% rename from crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__tupleassign.py.snap rename to crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__tupleassign.py.snap index 16f034ed48ce3..654b488efe275 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__tupleassign.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__tupleassign.py.snap @@ -1,6 +1,6 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/tupleassign.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/tupleassign.py --- ## Input diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__decorators.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__decorators.py.snap deleted file mode 100644 index 9eaba761d4f44..0000000000000 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__decorators.py.snap +++ /dev/null @@ -1,624 +0,0 @@ ---- -source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/decorators.py ---- -## Input - -```python -# This file doesn't use the standard decomposition. -# Decorator syntax test cases are separated by double # comments. -# Those before the 'output' comment are valid under the old syntax. -# Those after the 'ouput' comment require PEP614 relaxed syntax. -# Do not remove the double # separator before the first test case, it allows -# the comment before the test case to be ignored. - -## - -@decorator -def f(): - ... - -## - -@decorator() -def f(): - ... - -## - -@decorator(arg) -def f(): - ... - -## - -@decorator(kwarg=0) -def f(): - ... - -## - -@decorator(*args) -def f(): - ... - -## - -@decorator(**kwargs) -def f(): - ... - -## - -@decorator(*args, **kwargs) -def f(): - ... - -## - -@decorator(*args, **kwargs,) -def f(): - ... - -## - -@dotted.decorator -def f(): - ... - -## - -@dotted.decorator(arg) -def f(): - ... - -## - -@dotted.decorator(kwarg=0) -def f(): - ... - -## - -@dotted.decorator(*args) -def f(): - ... - -## - -@dotted.decorator(**kwargs) -def f(): - ... - -## - -@dotted.decorator(*args, **kwargs) -def f(): - ... - -## - -@dotted.decorator(*args, **kwargs,) -def f(): - ... - -## - -@double.dotted.decorator -def f(): - ... - -## - -@double.dotted.decorator(arg) -def f(): - ... - -## - -@double.dotted.decorator(kwarg=0) -def f(): - ... - -## - -@double.dotted.decorator(*args) -def f(): - ... - -## - -@double.dotted.decorator(**kwargs) -def f(): - ... - -## - -@double.dotted.decorator(*args, **kwargs) -def f(): - ... - -## - -@double.dotted.decorator(*args, **kwargs,) -def f(): - ... - -## - -@_(sequence["decorator"]) -def f(): - ... - -## - -@eval("sequence['decorator']") -def f(): - ... -``` - -## Black Differences - -```diff ---- Black -+++ Ruff -@@ -1,29 +1,206 @@ -+# This file doesn't use the standard decomposition. -+# Decorator syntax test cases are separated by double # comments. -+# Those before the 'output' comment are valid under the old syntax. -+# Those after the 'ouput' comment require PEP614 relaxed syntax. -+# Do not remove the double # separator before the first test case, it allows -+# the comment before the test case to be ignored. -+ -+## -+ -+ -+@decorator -+def f(): -+ ... -+ -+ -+## -+ -+ -+@decorator() -+def f(): -+ ... -+ -+ -+## -+ -+ -+@decorator(arg) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@decorator(kwarg=0) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@decorator(*args) -+def f(): -+ ... -+ -+ - ## - --@decorator()() -+ -+@decorator(**kwargs) - def f(): - ... - -+ - ## - --@(decorator) -+ -+@decorator(*args, **kwargs) - def f(): - ... - -+ - ## - --@sequence["decorator"] -+ -+@decorator( -+ *args, -+ **kwargs, -+) - def f(): - ... - -+ - ## - --@decorator[List[str]] -+ -+@dotted.decorator - def f(): - ... - -+ - ## - --@var := decorator -+ -+@dotted.decorator(arg) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@dotted.decorator(kwarg=0) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@dotted.decorator(*args) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@dotted.decorator(**kwargs) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@dotted.decorator(*args, **kwargs) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@dotted.decorator( -+ *args, -+ **kwargs, -+) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@double.dotted.decorator -+def f(): -+ ... -+ -+ -+## -+ -+ -+@double.dotted.decorator(arg) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@double.dotted.decorator(kwarg=0) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@double.dotted.decorator(*args) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@double.dotted.decorator(**kwargs) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@double.dotted.decorator(*args, **kwargs) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@double.dotted.decorator( -+ *args, -+ **kwargs, -+) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@_(sequence["decorator"]) -+def f(): -+ ... -+ -+ -+## -+ -+ -+@eval("sequence['decorator']") - def f(): - ... -``` - -## Ruff Output - -```python -# This file doesn't use the standard decomposition. -# Decorator syntax test cases are separated by double # comments. -# Those before the 'output' comment are valid under the old syntax. -# Those after the 'ouput' comment require PEP614 relaxed syntax. -# Do not remove the double # separator before the first test case, it allows -# the comment before the test case to be ignored. - -## - - -@decorator -def f(): - ... - - -## - - -@decorator() -def f(): - ... - - -## - - -@decorator(arg) -def f(): - ... - - -## - - -@decorator(kwarg=0) -def f(): - ... - - -## - - -@decorator(*args) -def f(): - ... - - -## - - -@decorator(**kwargs) -def f(): - ... - - -## - - -@decorator(*args, **kwargs) -def f(): - ... - - -## - - -@decorator( - *args, - **kwargs, -) -def f(): - ... - - -## - - -@dotted.decorator -def f(): - ... - - -## - - -@dotted.decorator(arg) -def f(): - ... - - -## - - -@dotted.decorator(kwarg=0) -def f(): - ... - - -## - - -@dotted.decorator(*args) -def f(): - ... - - -## - - -@dotted.decorator(**kwargs) -def f(): - ... - - -## - - -@dotted.decorator(*args, **kwargs) -def f(): - ... - - -## - - -@dotted.decorator( - *args, - **kwargs, -) -def f(): - ... - - -## - - -@double.dotted.decorator -def f(): - ... - - -## - - -@double.dotted.decorator(arg) -def f(): - ... - - -## - - -@double.dotted.decorator(kwarg=0) -def f(): - ... - - -## - - -@double.dotted.decorator(*args) -def f(): - ... - - -## - - -@double.dotted.decorator(**kwargs) -def f(): - ... - - -## - - -@double.dotted.decorator(*args, **kwargs) -def f(): - ... - - -## - - -@double.dotted.decorator( - *args, - **kwargs, -) -def f(): - ... - - -## - - -@_(sequence["decorator"]) -def f(): - ... - - -## - - -@eval("sequence['decorator']") -def f(): - ... -``` - -## Black Output - -```python -## - -@decorator()() -def f(): - ... - -## - -@(decorator) -def f(): - ... - -## - -@sequence["decorator"] -def f(): - ... - -## - -@decorator[List[str]] -def f(): - ... - -## - -@var := decorator -def f(): - ... -``` - - diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.py.snap index 4eeadc7a82b9d..c2d79524f4838 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.py.snap @@ -5,7 +5,6 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellan ## Input ```python -# flags: --pyi from typing import Union @bird @@ -43,8 +42,7 @@ def eggs() -> Union[str, int]: ... ```diff --- Black +++ Ruff -@@ -1,32 +1,59 @@ -+# flags: --pyi +@@ -1,32 +1,58 @@ from typing import Union + @@ -69,13 +67,13 @@ def eggs() -> Union[str, int]: ... - def BMethod(self, arg: List[str]) -> None: ... + def BMethod(self, arg: List[str]) -> None: + ... ++ ++ ++class C: ++ ... -class C: ... -+class C: -+ ... -+ -+ @hmm -class D: ... +class D: @@ -120,7 +118,6 @@ def eggs() -> Union[str, int]: ... ## Ruff Output ```python -# flags: --pyi from typing import Union diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.pyi.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.pyi.snap new file mode 100644 index 0000000000000..2eb67a391b12b --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.pyi.snap @@ -0,0 +1,128 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.pyi +--- +## Input + +```python +from typing import Union + +@bird +def zoo(): ... + +class A: ... +@bar +class B: + def BMethod(self) -> None: ... + @overload + def BMethod(self, arg : List[str]) -> None: ... + +class C: ... +@hmm +class D: ... +class E: ... + +@baz +def foo() -> None: + ... + +class F (A , C): ... +def spam() -> None: ... + +@overload +def spam(arg: str) -> str: ... + +var : int = 1 + +def eggs() -> Union[str, int]: ... +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -15,7 +15,6 @@ + + @hmm + class D: ... +- + class E: ... + + @baz +``` + +## Ruff Output + +```python +from typing import Union + +@bird +def zoo(): ... + +class A: ... + +@bar +class B: + def BMethod(self) -> None: ... + @overload + def BMethod(self, arg: List[str]) -> None: ... + +class C: ... + +@hmm +class D: ... +class E: ... + +@baz +def foo() -> None: ... + +class F(A, C): ... + +def spam() -> None: ... +@overload +def spam(arg: str) -> str: ... + +var: int = 1 + +def eggs() -> Union[str, int]: ... +``` + +## Black Output + +```python +from typing import Union + +@bird +def zoo(): ... + +class A: ... + +@bar +class B: + def BMethod(self) -> None: ... + @overload + def BMethod(self, arg: List[str]) -> None: ... + +class C: ... + +@hmm +class D: ... + +class E: ... + +@baz +def foo() -> None: ... + +class F(A, C): ... + +def spam() -> None: ... +@overload +def spam(arg: str) -> str: ... + +var: int = 1 + +def eggs() -> Union[str, int]: ... +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pattern_matching_extras.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pattern_matching_extras.py.snap deleted file mode 100644 index 865bb18e4453a..0000000000000 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_310__pattern_matching_extras.py.snap +++ /dev/null @@ -1,420 +0,0 @@ ---- -source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_extras.py ---- -## Input - -```python -import match - -match something: - case [a as b]: - print(b) - case [a as b, c, d, e as f]: - print(f) - case Point(a as b): - print(b) - case Point(int() as x, int() as y): - print(x, y) - - -match = 1 -case: int = re.match(something) - -match re.match(case): - case type("match", match): - pass - case match: - pass - - -def func(match: case, case: match) -> case: - match Something(): - case func(match, case): - ... - case another: - ... - - -match maybe, multiple: - case perhaps, 5: - pass - case perhaps, 6,: - pass - - -match more := (than, one), indeed,: - case _, (5, 6): - pass - case [[5], (6)], [7],: - pass - case _: - pass - - -match a, *b, c: - case [*_]: - assert "seq" == _ - case {}: - assert "map" == b - - -match match( - case, - match( - match, case, match, looooooooooooooooooooooooooooooooooooong, match, case, match - ), - case, -): - case case( - match=case, - case=re.match( - loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong - ), - ): - pass - - case [a as match]: - pass - - case case: - pass - - -match match: - case case: - pass - - -match a, *b(), c: - case d, *f, g: - pass - - -match something: - case { - "key": key as key_1, - "password": PASS.ONE | PASS.TWO | PASS.THREE as password, - }: - pass - case {"maybe": something(complicated as this) as that}: - pass - - -match something: - case 1 as a: - pass - - case 2 as b, 3 as c: - pass - - case 4 as d, (5 as e), (6 | 7 as g), *h: - pass - - -match bar1: - case Foo(aa=Callable() as aa, bb=int()): - print(bar1.aa, bar1.bb) - case _: - print("no match", "\n") - - -match bar1: - case Foo( - normal=x, perhaps=[list, {"x": d, "y": 1.0}] as y, otherwise=something, q=t as u - ): - pass -``` - -## Black Differences - -```diff ---- Black -+++ Ruff -@@ -32,14 +32,23 @@ - match maybe, multiple: - case perhaps, 5: - pass -- case perhaps, 6,: -+ case ( -+ perhaps, -+ 6, -+ ): - pass - - --match more := (than, one), indeed,: -+match ( -+ more := (than, one), -+ indeed, -+): - case _, (5, 6): - pass -- case [[5], (6)], [7],: -+ case [ -+ [[5], (6)], -+ [7], -+ ]: - pass - case _: - pass -``` - -## Ruff Output - -```python -import match - -match something: - case [a as b]: - print(b) - case [a as b, c, d, e as f]: - print(f) - case Point(a as b): - print(b) - case Point(int() as x, int() as y): - print(x, y) - - -match = 1 -case: int = re.match(something) - -match re.match(case): - case type("match", match): - pass - case match: - pass - - -def func(match: case, case: match) -> case: - match Something(): - case func(match, case): - ... - case another: - ... - - -match maybe, multiple: - case perhaps, 5: - pass - case ( - perhaps, - 6, - ): - pass - - -match ( - more := (than, one), - indeed, -): - case _, (5, 6): - pass - case [ - [[5], (6)], - [7], - ]: - pass - case _: - pass - - -match a, *b, c: - case [*_]: - assert "seq" == _ - case {}: - assert "map" == b - - -match match( - case, - match( - match, case, match, looooooooooooooooooooooooooooooooooooong, match, case, match - ), - case, -): - case case( - match=case, - case=re.match( - loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong - ), - ): - pass - - case [a as match]: - pass - - case case: - pass - - -match match: - case case: - pass - - -match a, *b(), c: - case d, *f, g: - pass - - -match something: - case { - "key": key as key_1, - "password": PASS.ONE | PASS.TWO | PASS.THREE as password, - }: - pass - case {"maybe": something(complicated as this) as that}: - pass - - -match something: - case 1 as a: - pass - - case 2 as b, 3 as c: - pass - - case 4 as d, (5 as e), (6 | 7 as g), *h: - pass - - -match bar1: - case Foo(aa=Callable() as aa, bb=int()): - print(bar1.aa, bar1.bb) - case _: - print("no match", "\n") - - -match bar1: - case Foo( - normal=x, perhaps=[list, {"x": d, "y": 1.0}] as y, otherwise=something, q=t as u - ): - pass -``` - -## Black Output - -```python -import match - -match something: - case [a as b]: - print(b) - case [a as b, c, d, e as f]: - print(f) - case Point(a as b): - print(b) - case Point(int() as x, int() as y): - print(x, y) - - -match = 1 -case: int = re.match(something) - -match re.match(case): - case type("match", match): - pass - case match: - pass - - -def func(match: case, case: match) -> case: - match Something(): - case func(match, case): - ... - case another: - ... - - -match maybe, multiple: - case perhaps, 5: - pass - case perhaps, 6,: - pass - - -match more := (than, one), indeed,: - case _, (5, 6): - pass - case [[5], (6)], [7],: - pass - case _: - pass - - -match a, *b, c: - case [*_]: - assert "seq" == _ - case {}: - assert "map" == b - - -match match( - case, - match( - match, case, match, looooooooooooooooooooooooooooooooooooong, match, case, match - ), - case, -): - case case( - match=case, - case=re.match( - loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong - ), - ): - pass - - case [a as match]: - pass - - case case: - pass - - -match match: - case case: - pass - - -match a, *b(), c: - case d, *f, g: - pass - - -match something: - case { - "key": key as key_1, - "password": PASS.ONE | PASS.TWO | PASS.THREE as password, - }: - pass - case {"maybe": something(complicated as this) as that}: - pass - - -match something: - case 1 as a: - pass - - case 2 as b, 3 as c: - pass - - case 4 as d, (5 as e), (6 | 7 as g), *h: - pass - - -match bar1: - case Foo(aa=Callable() as aa, bb=int()): - print(bar1.aa, bar1.bb) - case _: - print("no match", "\n") - - -match bar1: - case Foo( - normal=x, perhaps=[list, {"x": d, "y": 1.0}] as y, otherwise=something, q=t as u - ): - pass -``` - - diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__docstring_preview.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__docstring_preview.py.snap deleted file mode 100644 index afb73efb11279..0000000000000 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__docstring_preview.py.snap +++ /dev/null @@ -1,184 +0,0 @@ ---- -source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring_preview.py ---- -## Input - -```python -def docstring_almost_at_line_limit(): - """long docstring................................................................. - """ - - -def docstring_almost_at_line_limit_with_prefix(): - f"""long docstring................................................................ - """ - - -def mulitline_docstring_almost_at_line_limit(): - """long docstring................................................................. - - .................................................................................. - """ - - -def mulitline_docstring_almost_at_line_limit_with_prefix(): - f"""long docstring................................................................ - - .................................................................................. - """ - - -def docstring_at_line_limit(): - """long docstring................................................................""" - - -def docstring_at_line_limit_with_prefix(): - f"""long docstring...............................................................""" - - -def multiline_docstring_at_line_limit(): - """first line----------------------------------------------------------------------- - - second line----------------------------------------------------------------------""" - - -def multiline_docstring_at_line_limit_with_prefix(): - f"""first line---------------------------------------------------------------------- - - second line----------------------------------------------------------------------""" - - -def single_quote_docstring_over_line_limit(): - "We do not want to put the closing quote on a new line as that is invalid (see GH-3141)." - - -def single_quote_docstring_over_line_limit2(): - 'We do not want to put the closing quote on a new line as that is invalid (see GH-3141).' -``` - -## Black Differences - -```diff ---- Black -+++ Ruff -@@ -3,7 +3,8 @@ - - - def docstring_almost_at_line_limit_with_prefix(): -- f"""long docstring................................................................""" -+ f"""long docstring................................................................ -+ """ - - - def mulitline_docstring_almost_at_line_limit(): -``` - -## Ruff Output - -```python -def docstring_almost_at_line_limit(): - """long docstring.................................................................""" - - -def docstring_almost_at_line_limit_with_prefix(): - f"""long docstring................................................................ - """ - - -def mulitline_docstring_almost_at_line_limit(): - """long docstring................................................................. - - .................................................................................. - """ - - -def mulitline_docstring_almost_at_line_limit_with_prefix(): - f"""long docstring................................................................ - - .................................................................................. - """ - - -def docstring_at_line_limit(): - """long docstring................................................................""" - - -def docstring_at_line_limit_with_prefix(): - f"""long docstring...............................................................""" - - -def multiline_docstring_at_line_limit(): - """first line----------------------------------------------------------------------- - - second line----------------------------------------------------------------------""" - - -def multiline_docstring_at_line_limit_with_prefix(): - f"""first line---------------------------------------------------------------------- - - second line----------------------------------------------------------------------""" - - -def single_quote_docstring_over_line_limit(): - "We do not want to put the closing quote on a new line as that is invalid (see GH-3141)." - - -def single_quote_docstring_over_line_limit2(): - "We do not want to put the closing quote on a new line as that is invalid (see GH-3141)." -``` - -## Black Output - -```python -def docstring_almost_at_line_limit(): - """long docstring.................................................................""" - - -def docstring_almost_at_line_limit_with_prefix(): - f"""long docstring................................................................""" - - -def mulitline_docstring_almost_at_line_limit(): - """long docstring................................................................. - - .................................................................................. - """ - - -def mulitline_docstring_almost_at_line_limit_with_prefix(): - f"""long docstring................................................................ - - .................................................................................. - """ - - -def docstring_at_line_limit(): - """long docstring................................................................""" - - -def docstring_at_line_limit_with_prefix(): - f"""long docstring...............................................................""" - - -def multiline_docstring_at_line_limit(): - """first line----------------------------------------------------------------------- - - second line----------------------------------------------------------------------""" - - -def multiline_docstring_at_line_limit_with_prefix(): - f"""first line---------------------------------------------------------------------- - - second line----------------------------------------------------------------------""" - - -def single_quote_docstring_over_line_limit(): - "We do not want to put the closing quote on a new line as that is invalid (see GH-3141)." - - -def single_quote_docstring_over_line_limit2(): - "We do not want to put the closing quote on a new line as that is invalid (see GH-3141)." -``` - - diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__preview_hug_parens_with_braces_and_square_brackets.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__preview_hug_parens_with_braces_and_square_brackets.py.snap new file mode 100644 index 0000000000000..df9471aac22dc --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__preview_hug_parens_with_braces_and_square_brackets.py.snap @@ -0,0 +1,543 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/preview_hug_parens_with_braces_and_square_brackets.py +--- +## Input + +```python +def foo_brackets(request): + return JsonResponse( + { + "var_1": foo, + "var_2": bar, + } + ) + +def foo_square_brackets(request): + return JsonResponse( + [ + "var_1", + "var_2", + ] + ) + +func({"a": 37, "b": 42, "c": 927, "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111}) + +func(["random_string_number_one","random_string_number_two","random_string_number_three","random_string_number_four"]) + +func( + { + # expand me + 'a':37, + 'b':42, + 'c':927 + } +) + +func( + [ + 'a', + 'b', + 'c', + ] +) + +func( + [ + 'a', + 'b', + 'c', + ], +) + +func( # a + [ # b + "c", # c + "d", # d + "e", # e + ] # f +) # g + +func( # a + { # b + "c": 1, # c + "d": 2, # d + "e": 3, # e + } # f +) # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func( + [ # preserve me but hug brackets + "c", + "d", + "e", + ] +) + +func( + [ + # preserve me but hug brackets + "c", + "d", + "e", + ] +) + +func( + [ + "c", + # preserve me but hug brackets + "d", + "e", + ] +) + +func( + [ + "c", + "d", + "e", + # preserve me but hug brackets + ] +) + +func( + [ + "c", + "d", + "e", + ] # preserve me but hug brackets +) + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func([x for x in "long line long line long line long line long line long line long line"]) +func([x for x in [x for x in "long line long line long line long line long line long line long line"]]) + +func({"short line"}) +func({"long line", "long long line", "long long long line", "long long long long line", "long long long long long line"}) +func({{"long line", "long long line", "long long long line", "long long long long line", "long long long long long line"}}) + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +foo(*["long long long long long line", "long long long long long line", "long long long long long line"]) + +foo(*[str(i) for i in range(100000000000000000000000000000000000000000000000000000000000)]) +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -47,17 +47,21 @@ + ], + ) + +-func([ # a # b +- "c", # c +- "d", # d +- "e", # e +-]) # f # g ++func( # a ++ [ # b ++ "c", # c ++ "d", # d ++ "e", # e ++ ] # f ++) # g + +-func({ # a # b +- "c": 1, # c +- "d": 2, # d +- "e": 3, # e +-}) # f # g ++func( # a ++ { # b ++ "c": 1, # c ++ "d": 2, # d ++ "e": 3, # e ++ } # f ++) # g + + func( + # preserve me +@@ -95,11 +99,13 @@ + # preserve me but hug brackets + ]) + +-func([ +- "c", +- "d", +- "e", +-]) # preserve me but hug brackets ++func( ++ [ ++ "c", ++ "d", ++ "e", ++ ] # preserve me but hug brackets ++) + + func( + [ +``` + +## Ruff Output + +```python +def foo_brackets(request): + return JsonResponse({ + "var_1": foo, + "var_2": bar, + }) + + +def foo_square_brackets(request): + return JsonResponse([ + "var_1", + "var_2", + ]) + + +func({ + "a": 37, + "b": 42, + "c": 927, + "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111, +}) + +func([ + "random_string_number_one", + "random_string_number_two", + "random_string_number_three", + "random_string_number_four", +]) + +func({ + # expand me + "a": 37, + "b": 42, + "c": 927, +}) + +func([ + "a", + "b", + "c", +]) + +func( + [ + "a", + "b", + "c", + ], +) + +func( # a + [ # b + "c", # c + "d", # d + "e", # e + ] # f +) # g + +func( # a + { # b + "c": 1, # c + "d": 2, # d + "e": 3, # e + } # f +) # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func([ # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + "c", + # preserve me but hug brackets + "d", + "e", +]) + +func([ + "c", + "d", + "e", + # preserve me but hug brackets +]) + +func( + [ + "c", + "d", + "e", + ] # preserve me but hug brackets +) + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func([ + x for x in "long line long line long line long line long line long line long line" +]) +func([ + x + for x in [ + x + for x in "long line long line long line long line long line long line long line" + ] +]) + +func({"short line"}) +func({ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +}) +func({ + { + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", + } +}) + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +foo(*[ + "long long long long long line", + "long long long long long line", + "long long long long long line", +]) + +foo(*[ + str(i) for i in range(100000000000000000000000000000000000000000000000000000000000) +]) +``` + +## Black Output + +```python +def foo_brackets(request): + return JsonResponse({ + "var_1": foo, + "var_2": bar, + }) + + +def foo_square_brackets(request): + return JsonResponse([ + "var_1", + "var_2", + ]) + + +func({ + "a": 37, + "b": 42, + "c": 927, + "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111111111111111111, +}) + +func([ + "random_string_number_one", + "random_string_number_two", + "random_string_number_three", + "random_string_number_four", +]) + +func({ + # expand me + "a": 37, + "b": 42, + "c": 927, +}) + +func([ + "a", + "b", + "c", +]) + +func( + [ + "a", + "b", + "c", + ], +) + +func([ # a # b + "c", # c + "d", # d + "e", # e +]) # f # g + +func({ # a # b + "c": 1, # c + "d": 2, # d + "e": 3, # e +}) # f # g + +func( + # preserve me + [ + "c", + "d", + "e", + ] +) + +func([ # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + # preserve me but hug brackets + "c", + "d", + "e", +]) + +func([ + "c", + # preserve me but hug brackets + "d", + "e", +]) + +func([ + "c", + "d", + "e", + # preserve me but hug brackets +]) + +func([ + "c", + "d", + "e", +]) # preserve me but hug brackets + +func( + [ + "c", + "d", + "e", + ] + # preserve me +) + +func([x for x in "short line"]) +func([ + x for x in "long line long line long line long line long line long line long line" +]) +func([ + x + for x in [ + x + for x in "long line long line long line long line long line long line long line" + ] +]) + +func({"short line"}) +func({ + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", +}) +func({ + { + "long line", + "long long line", + "long long long line", + "long long long long line", + "long long long long long line", + } +}) + +foooooooooooooooooooo( + [{c: n + 1 for c in range(256)} for n in range(100)] + [{}], {size} +) + +baaaaaaaaaaaaar( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], {x}, "a string", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +) + +foo(*[ + "long long long long long line", + "long long long long long line", + "long long long long long line", +]) + +foo(*[ + str(i) for i in range(100000000000000000000000000000000000000000000000000000000000) +]) +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap index 4e92b7c09db29..bf8fa7f40df94 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap @@ -156,17 +156,25 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + ' content\ ' + return ``` ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -322,17 +330,25 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + "content\ " + return ``` ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 2 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 2 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -488,17 +504,25 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + "content\ " + return ``` ### Output 3 ``` -indent-style = tab -line-width = 88 -indent-width = 8 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = tab +line-width = 88 +indent-width = 8 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -654,17 +678,25 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + "content\ " + return ``` ### Output 4 ``` -indent-style = tab -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = tab +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -820,6 +852,185 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + "content\ " + return +``` + + +### Output 5 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Single +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +def single_line_backslashes1(): + """content\ """ + return + + +def single_line_backslashes2(): + """content\\""" + return + + +def single_line_backslashes3(): + """content\\\ """ + return + + +def multiline_backslashes1(): + """This is a docstring with + some lines of text\ """ + return + + +def multiline_backslashes2(): + """This is a docstring with + some lines of text\\""" + return + + +def multiline_backslashes3(): + """This is a docstring with + some lines of text\\\ """ + return + + +def multiple_negatively_indented_docstring_lines(): + """a + b + c + d + e + """ + + +def overindentend_docstring(): + """a + over-indented + """ + + +def comment_before_docstring(): + # don't lose this function comment ... + """Does nothing. + + But it has comments + """ # ... neither lose this function comment + + +class CommentBeforeDocstring: + # don't lose this class comment ... + """Empty class. + + But it has comments + """ # ... neither lose this class comment + + +class IndentMeSome: + def doc_string_without_linebreak_after_colon(self): + """This is somewhat strange + a + b + We format this a is the docstring had started properly indented on the next + line if the target indentation. This may we incorrect since source and target + indentation can be incorrect, but this is also an edge case. + """ + + +class IgnoreImplicitlyConcatenatedStrings: + """""" '' + + +def docstring_that_ends_with_quote_and_a_line_break1(): + """ + he said "the news of my death have been greatly exaggerated" + """ + + +def docstring_that_ends_with_quote_and_a_line_break2(): + """he said "the news of my death have been greatly exaggerated" """ + + +def docstring_that_ends_with_quote_and_a_line_break3(): + """he said "the news of my death have been greatly exaggerated" """ + + +class ByteDocstring: + b""" has leading whitespace""" + first_statement = 1 + + +class CommentAfterDocstring1: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + def __init__(self): + pass + + +class CommentAfterDocstring2: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + def __init__(self): + pass + + +class CommentAfterDocstring3: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + def __init__(self): + pass + + +class CommentAfterDocstring4: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + def __init__(self): + pass + + +class CommentAfterDocstring5: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + +def f(): + """Browse module classes and functions in IDLE.""" + # ^ Do not insert a newline above here + + pass + + +class TabbedIndent: + def tabbed_indent(self): + """check for correct tabbed formatting + ^^^^^^^^^^ + Normal indented line + - autor + """ + + +def single_quoted(): + "content\ " + return ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples.py.snap new file mode 100644 index 0000000000000..672b7a715d623 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples.py.snap @@ -0,0 +1,15060 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples.py +--- +## Input +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + >>> cool_stuff( y ) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x )""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + ... more( y )""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... + ... print( x ) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested( x ): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + ''' + Do cool stuff. + + >>> assert ("Easy!") + >>> import math + >>> math.floor( 1.9 ) + 1 + ''' + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + ''' + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard) + ''' + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( x ) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff( 1 )""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff( 1 ) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff( 1 ) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff( 1 ) + cool_stuff( 2 ) + cool_stuff( 3 ) + cool_stuff( 4 ) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff( x ): + print( f"hi {x}" ); + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff( 1 ) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ```invalid + ''' + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( ''' + ``` + did i trick you? + ``` + ''' ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + + + """ + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 )""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + + + cool_stuff( 1 ) + + + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff( 1 ) + + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print( 5 ) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py +cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + +## Outputs +### Output 1 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + >>> cool_stuff( y ) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x )""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + ... more( y )""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... + ... print( x ) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested( x ): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert ("Easy!") + >>> import math + >>> math.floor( 1.9 ) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( x ) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff( 1 )""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff( 1 ) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff( 1 ) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff( 1 ) + cool_stuff( 2 ) + cool_stuff( 3 ) + cool_stuff( 4 ) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff( x ): + print( f"hi {x}" ); + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff( 1 ) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ```invalid + ''' + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( ''' + ``` + did i trick you? + ``` + ''' ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + + + """ + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 )""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + + + cool_stuff( 1 ) + + + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff( 1 ) + + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print( 5 ) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 2 +``` +indent-style = space +line-width = 88 +indent-width = 2 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + >>> cool_stuff( y ) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x )""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + ... more( y )""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... + ... print( x ) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested( x ): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert ("Easy!") + >>> import math + >>> math.floor( 1.9 ) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( x ) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff( 1 )""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff( 1 ) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff( 1 ) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff( 1 ) + cool_stuff( 2 ) + cool_stuff( 3 ) + cool_stuff( 4 ) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff( x ): + print( f"hi {x}" ); + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff( 1 ) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ```invalid + ''' + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( ''' + ``` + did i trick you? + ``` + ''' ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + + + """ + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 )""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + + + cool_stuff( 1 ) + + + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff( 1 ) + + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print( 5 ) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 3 +``` +indent-style = tab +line-width = 88 +indent-width = 8 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + >>> cool_stuff( y ) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x )""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + ... more( y )""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... + ... print( x ) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested( x ): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert ("Easy!") + >>> import math + >>> math.floor( 1.9 ) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( x ) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff( 1 )""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff( 1 ) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff( 1 ) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff( 1 ) + cool_stuff( 2 ) + cool_stuff( 3 ) + cool_stuff( 4 ) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff( x ): + print( f"hi {x}" ); + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff( 1 ) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ```invalid + ''' + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( ''' + ``` + did i trick you? + ``` + ''' ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + + + """ + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 )""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + + + cool_stuff( 1 ) + + + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff( 1 ) + + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print( 5 ) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 4 +``` +indent-style = tab +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + >>> cool_stuff( y ) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff( x )""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff( x ) + ... more( y )""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... + ... print( x ) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff ( x ): + ... print( x ) + ... print( x ) + ... + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested( x ): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert ("Easy!") + >>> import math + >>> math.floor( 1.9 ) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line(lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( x ) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff( 1 )""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff( 1 ) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff( 1 ) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff( 1 ) + cool_stuff( 2 ) + cool_stuff( 3 ) + cool_stuff( 4 ) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff( x ): + print( f"hi {x}" ); + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff( 1 ) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ```invalid + ''' + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( ''' + ``` + did i trick you? + ``` + ''' ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + + + """ + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + """ + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 )""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff( x ): + print( f"hi {x}" ); + + def other_stuff( y ): + print( y ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + + + cool_stuff( 1 ) + + + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + + cool_stuff( 1 ) + + + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff( 1 ) + + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print( 5 ) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 5 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff(1) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff(x) + >>> cool_stuff(y) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x)""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff(x) + ... more(y)""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested(x): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert "Easy!" + >>> import math + >>> math.floor(1.9) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey + ... ) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard + ... ) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff(1) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff(1)""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff(1) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff(1) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff(1) + + + cool_stuff(2) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( + ''' + hiya''' + ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff(1) + cool_stuff(2) + cool_stuff(3) + cool_stuff(4) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff(1) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff(x): + print(f"hi {x}") + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff(1) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ''' + ```invalid + ''' + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( + ''' + ``` + did i trick you? + ``` + ''' + ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + + + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff(1) + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print(5) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 6 +``` +indent-style = space +line-width = 88 +indent-width = 2 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff(1) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff(x) + >>> cool_stuff(y) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x)""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff(x) + ... more(y)""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested(x): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert "Easy!" + >>> import math + >>> math.floor(1.9) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey + ... ) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard + ... ) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff(1) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff(1)""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff(1) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff(1) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff(1) + + + cool_stuff(2) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( + ''' + hiya''' + ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff(1) + cool_stuff(2) + cool_stuff(3) + cool_stuff(4) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff(1) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff(x): + print(f"hi {x}") + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff(1) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ''' + ```invalid + ''' + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( + ''' + ``` + did i trick you? + ``` + ''' + ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + + + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff(1) + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print(5) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 7 +``` +indent-style = tab +line-width = 88 +indent-width = 8 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff(1) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff(x) + >>> cool_stuff(y) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x)""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff(x) + ... more(y)""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested(x): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert "Easy!" + >>> import math + >>> math.floor(1.9) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey + ... ) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, + ... giraffe, + ... hippo, + ... zeba, + ... lemur, + ... penguin, + ... monkey, + ... spider, + ... bear, + ... leopard, + ... ) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff(1) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff(1)""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff(1) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff(1) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff(1) + + + cool_stuff(2) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( + ''' + hiya''' + ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff(1) + cool_stuff(2) + cool_stuff(3) + cool_stuff(4) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff(1) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff(x): + print(f"hi {x}") + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff(1) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ''' + ```invalid + ''' + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( + ''' + ``` + did i trick you? + ``` + ''' + ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + + + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff(1) + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print(5) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 8 +``` +indent-style = tab +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff(1) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff(x) + >>> cool_stuff(y) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x)""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff(x) + ... more(y)""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested(x): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert "Easy!" + >>> import math + >>> math.floor(1.9) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey + ... ) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard + ... ) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff(1) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff(1)""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff(1) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff(1) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff(1) + + + cool_stuff(2) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( + ''' + hiya''' + ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff(1) + cool_stuff(2) + cool_stuff(3) + cool_stuff(4) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff(1) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff(x): + print(f"hi {x}") + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff(1) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ''' + ```invalid + ''' + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( + ''' + ``` + did i trick you? + ``` + ''' + ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + + + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff(1) + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print(5) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 9 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = 60 +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff(1) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff(x) + >>> cool_stuff(y) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x)""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff(x) + ... more(y)""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested(x): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert "Easy!" + >>> import math + >>> math.floor(1.9) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey + ... ) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, + ... giraffe, + ... hippo, + ... zeba, + ... lemur, + ... penguin, + ... monkey, + ... spider, + ... bear, + ... leopard, + ... ) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff(1) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff(1)""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff(1) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff(1) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff(1) + + + cool_stuff(2) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( + ''' + hiya''' + ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff(1) + cool_stuff(2) + cool_stuff(3) + cool_stuff(4) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff(1) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff(x): + print(f"hi {x}") + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff(1) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ''' + ```invalid + ''' + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( + ''' + ``` + did i trick you? + ``` + ''' + ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + + + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff(1) + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print(5) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + +### Output 10 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +############################################################################### +# DOCTEST CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Python's "doctest" format. +# +# See: https://docs.python.org/3/library/doctest.html +############################################################################### + +# The simplest doctest to ensure basic formatting works. +def doctest_simple(): + """ + Do cool stuff. + + >>> cool_stuff(1) + 2 + """ + pass + + +# Another simple test, but one where the Python code +# extends over multiple lines. +def doctest_simple_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + hi 2 + """ + pass + + +# Test that we support multiple directly adjacent +# doctests. +def doctest_adjacent(): + """ + Do cool stuff. + + >>> cool_stuff(x) + >>> cool_stuff(y) + 2 + """ + pass + + +# Test that a doctest on the last non-whitespace line of a docstring +# reformats correctly. +def doctest_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x) + """ + pass + + +# Test that a doctest that continues to the last non-whitespace line of +# a docstring reformats correctly. +def doctest_last_line_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(f"hi {x}") + """ + pass + + +# Test that a doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line(): + """ + Do cool stuff. + + >>> cool_stuff(x)""" + pass + + +# Test that a continued doctest on the real last line of a docstring reformats +# correctly. +def doctest_really_last_line_continued(): + """ + Do cool stuff. + + >>> cool_stuff(x) + ... more(y)""" + pass + + +# Test that a doctest is correctly identified and formatted with a blank +# continuation line. +def doctest_blank_continued(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped. +# It is treated as part of the Python snippet which will trim the +# trailing whitespace. +def doctest_blank_end(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + """ + pass + + +# Tests that a blank PS2 line at the end of a doctest can get dropped +# even when there is text following it. +def doctest_blank_end_then_some_text(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print(x) + + And say something else. + """ + pass + + +# Test that a doctest containing a triple quoted string gets formatted +# correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = '''tricksy''' + """ + pass + + +# Test that a doctest containing a triple quoted f-string gets +# formatted correctly and doesn't result in invalid syntax. +def doctest_with_triple_single(): + """ + Do cool stuff. + + >>> x = f'''tricksy''' + """ + pass + + +# Another nested multi-line string case, but with triple escaped double +# quotes inside a triple single quoted string. +def doctest_with_triple_escaped_double(): + """ + Do cool stuff. + + >>> x = '''\"\"\"''' + """ + pass + + +# Tests that inverting the triple quoting works as expected. +def doctest_with_triple_inverted(): + ''' + Do cool stuff. + + >>> x = """tricksy""" + ''' + pass + + +# Tests that inverting the triple quoting with an f-string works as +# expected. +def doctest_with_triple_inverted_fstring(): + ''' + Do cool stuff. + + >>> x = f"""tricksy""" + ''' + pass + + +# Tests nested doctests are ignored. That is, we don't format doctests +# recursively. We only recognize "top level" doctests. +# +# This restriction primarily exists to avoid needing to deal with +# nesting quotes. It also seems like a generally sensible restriction, +# although it could be lifted if necessary I believe. +def doctest_nested_doctest_not_formatted(): + ''' + Do cool stuff. + + >>> def nested(x): + ... """ + ... Do nested cool stuff. + ... >>> func_call( 5 ) + ... """ + ... pass + ''' + pass + + +# Tests that the starting column does not matter. +def doctest_varying_start_column(): + """ + Do cool stuff. + + >>> assert "Easy!" + >>> import math + >>> math.floor(1.9) + 1 + """ + pass + + +# Tests that long lines get wrapped... appropriately. +# +# The docstring code formatter uses the same line width settings as for +# formatting other code. This means that a line in the docstring can +# actually extend past the configured line limit. +# +# It's not quite clear whether this is desirable or not. We could in +# theory compute the intendation length of a code snippet and then +# adjust the line-width setting on a recursive call to the formatter. +# But there are assuredly pathological cases to consider. Another path +# would be to expose another formatter option for controlling the +# line-width of code snippets independently. +def doctest_long_lines(): + """ + Do cool stuff. + + This won't get wrapped even though it exceeds our configured + line width because it doesn't exceed the line width within this + docstring. e.g, the `f` in `foo` is treated as the first column. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey + ... ) + + But this one is long enough to get wrapped. + >>> foo, bar, quux = this_is_a_long_line( + ... lion, giraffe, hippo, zeba, lemur, penguin, monkey, spider, bear, leopard + ... ) + """ + # This demostrates a normal line that will get wrapped but won't + # get wrapped in the docstring above because of how the line-width + # setting gets reset at the first column in each code snippet. + foo, bar, quux = this_is_a_long_line( + lion, giraffe, hippo, zeba, lemur, penguin, monkey + ) + + +# Checks that a simple but invalid doctest gets skipped. +def doctest_skipped_simple(): + """ + Do cool stuff. + + >>> cool-stuff( x ): + 2 + """ + pass + + +# Checks that a simple doctest that is continued over multiple lines, +# but is invalid, gets skipped. +def doctest_skipped_simple_continued(): + """ + Do cool stuff. + + >>> def cool-stuff( x ): + ... print( f"hi {x}" ); + 2 + """ + pass + + +# Checks that a doctest with improper indentation gets skipped. +def doctest_skipped_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff( x ): + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with some proper indentation and some improper +# indentation is "partially" formatted. That is, the part that appears +# before the inconsistent indentation is formatted. This requires that +# the part before it is valid Python. +def doctest_skipped_partial_inconsistent_indent(): + """ + Do cool stuff. + + >>> def cool_stuff(x): + ... print(x) + ... print( f"hi {x}" ); + hi 2 + """ + pass + + +# Checks that a doctest with improper triple single quoted string gets +# skipped. That is, the code snippet is itself invalid Python, so it is +# left as is. +def doctest_skipped_triple_incorrect(): + """ + Do cool stuff. + + >>> foo( x ) + ... '''tri'''cksy''' + """ + pass + + +# Tests that a doctest on a single line is skipped. +def doctest_skipped_one_line(): + ">>> foo( x )" + pass + + +# f-strings are not considered docstrings[1], so any doctests +# inside of them should not be formatted. +# +# [1]: https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals +def doctest_skipped_fstring(): + f""" + Do cool stuff. + + >>> cool_stuff( 1 ) + 2 + """ + pass + + +# Test that a doctest containing a triple quoted string at least +# does not result in invalid Python code. Ideally this would format +# correctly, but at time of writing it does not. +def doctest_invalid_skipped_with_triple_double_in_single_quote_string(): + """ + Do cool stuff. + + >>> x = '\"\"\"' + """ + pass + + +############################################################################### +# reStructuredText CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# reStructuredText formatted code blocks. +# +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks +# See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-30 +# See: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#toc-entry-38 +############################################################################### + + +def rst_literal_simple(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_literal_simple_continued(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + Done. + """ + pass + + +# Tests that we can end the literal block on the second +# to last line of the docstring. +def rst_literal_second_to_last(): + """ + Do cool stuff:: + + cool_stuff(1) + """ + pass + + +# Tests that we can end the literal block on the actual +# last line of the docstring. +def rst_literal_actually_last(): + """ + Do cool stuff:: + + cool_stuff(1)""" + pass + + +def rst_literal_with_blank_lines(): + """ + Do cool stuff:: + + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + + Done. + """ + pass + + +# Extra blanks should be preserved. +def rst_literal_extra_blanks(): + """ + Do cool stuff:: + + + + cool_stuff(1) + + + + Done. + """ + pass + + +# If a literal block is never properly ended (via a non-empty unindented line), +# then the end of the block should be the last non-empty line. And subsequent +# empty lines should be preserved as-is. +def rst_literal_extra_blanks_at_end(): + """ + Do cool stuff:: + + + cool_stuff(1) + + + + """ + pass + + +# A literal block can contain many empty lines and it should not end the block +# if it continues. +def rst_literal_extra_blanks_in_snippet(): + """ + Do cool stuff:: + + cool_stuff(1) + + + cool_stuff(2) + + Done. + """ + pass + + +# This tests that a unindented line appearing after an indented line (but where +# the indent is still beyond the minimum) gets formatted properly. +def rst_literal_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( + ''' + hiya''' + ) + + Done. + """ + pass + + +# This checks that if the first line in a code snippet has been indented with +# tabs, then so long as its "indentation length" is considered bigger than the +# line with `::`, it is reformatted as code. +# +# (If your tabwidth is set to 4, then it looks like the code snippet +# isn't indented at all, which is perhaps counter-intuitive. Indeed, reST +# itself also seems to recognize this as a code block, although it appears +# under-specified.) +def rst_literal_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Another test with tabs, except in this case, if your tabwidth is less than +# 8, than the code snippet actually looks like its indent is *less* than the +# opening line with a `::`. One might presume this means that the code snippet +# is not treated as a literal block and thus not reformatted, but since we +# assume all tabs have tabwidth=8 when computing indentation length, the code +# snippet is actually seen as being more indented than the opening `::` line. +# As with the above example, reST seems to behave the same way here. +def rst_literal_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + + Done. + """ + pass + + +# Like the test above, but with multiple lines. +def rst_literal_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that if two lines in a literal block are indented to the same level +# but by different means (tabs versus spaces), then we correctly recognize the +# block and format it. +def rst_literal_first_line_tab_second_line_spaces(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that when two lines in a code snippet have weird and inconsistent +# indentation, the code still gets formatted so long as the indent is greater +# than the indent of the `::` line. +# +# In this case, the minimum indent is 5 spaces (from the second line) where as +# the first line has an indent of 8 spaces via a tab (by assuming tabwidth=8). +# The minimum indent is stripped from each code line. Since tabs aren't +# divisible, the entire tab is stripped, which means the first and second lines +# wind up with the same level of indentation. +# +# An alternative behavior here would be that the tab is replaced with 3 spaces +# instead of being stripped entirely. The code snippet itself would then have +# inconsistent indentation to the point of being invalid Python, and thus code +# formatting would be skipped. +# +# I decided on the former behavior because it seems a bit easier to implement, +# but we might want to switch to the alternative if cases like this show up in +# the real world. ---AG +def rst_literal_odd_indentation(): + """ + Do cool stuff:: + + cool_stuff(1) + cool_stuff(2) + + Done. + """ + pass + + +# Tests that having a line with a lone `::` works as an introduction of a +# literal block. +def rst_literal_lone_colon(): + """ + Do cool stuff. + + :: + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_simple(): + """ + .. code-block:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_case_insensitive(): + """ + .. cOdE-bLoCk:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_sourcecode(): + """ + .. sourcecode:: python + + cool_stuff(1) + + Done. + """ + pass + + +def rst_directive_options(): + """ + .. code-block:: python + :linenos: + :emphasize-lines: 2,3 + :name: blah blah + + cool_stuff(1) + cool_stuff(2) + cool_stuff(3) + cool_stuff(4) + + Done. + """ + pass + + +# In this case, since `pycon` isn't recognized as a Python code snippet, the +# docstring reformatter ignores it. But it then picks up the doctest and +# reformats it. +def rst_directive_doctest(): + """ + .. code-block:: pycon + + >>> cool_stuff(1) + + Done. + """ + pass + + +# This checks that if the first non-empty line after the start of a literal +# block is not indented more than the line containing the `::`, then it is not +# treated as a code snippet. +def rst_literal_skipped_first_line_not_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the test above, but inserts an indented line after the un-indented one. +# This should not cause the literal block to be resumed. +def rst_literal_skipped_first_line_not_indented_then_indented(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# This also checks that a code snippet is not reformatted when the indentation +# of the first line is not more than the line with `::`, but this uses tabs to +# make it a little more confounding. It relies on the fact that indentation +# length is computed by assuming a tabwidth equal to 8. reST also rejects this +# and doesn't treat it as a literal block. +def rst_literal_skipped_first_line_not_indented_tab(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# Like the previous test, but adds a second line. +def rst_literal_skipped_first_line_not_indented_tab_multiple(): + """ + Do cool stuff:: + + cool_stuff( 1 ) + cool_stuff( 2 ) + + Done. + """ + pass + + +# Tests that a code block with a second line that is not properly indented gets +# skipped. A valid code block needs to have an empty line separating these. +# +# One trick here is that we need to make sure the Python code in the snippet is +# valid, otherwise it would be skipped because of invalid Python. +def rst_literal_skipped_subsequent_line_not_indented(): + """ + Do cool stuff:: + + if True: + cool_stuff( ''' + hiya''' ) + + Done. + """ + pass + + +# In this test, we write what looks like a code-block, but it should be treated +# as invalid due to the missing `language` argument. +# +# It does still look like it could be a literal block according to the literal +# rules, but we currently consider the `.. ` prefix to indicate that it is not +# a literal block. +def rst_literal_skipped_not_directive(): + """ + .. code-block:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# In this test, we start a line with `.. `, which makes it look like it might +# be a directive. But instead continue it as if it was just some periods from +# the previous line, and then try to end it by starting a literal block. +# +# But because of the `.. ` in the beginning, we wind up not treating this as a +# code snippet. The reST render I was using to test things does actually treat +# this as a code block, so we may be out of conformance here. +def rst_literal_skipped_possible_false_negative(): + """ + This is a test. + .. This is a test:: + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This tests that a doctest inside of a reST literal block doesn't get +# reformatted. It's plausible this isn't the right behavior, but it also seems +# like it might be the right behavior since it is a literal block. (The doctest +# makes the Python code invalid.) +def rst_literal_skipped_doctest(): + """ + Do cool stuff:: + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_literal_skipped_markdown(): + """ + Do cool stuff:: + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def rst_directive_skipped_not_indented(): + """ + .. code-block:: python + + cool_stuff( 1 ) + + Done. + """ + pass + + +def rst_directive_skipped_wrong_language(): + """ + .. code-block:: rust + + cool_stuff( 1 ) + + Done. + """ + pass + + +# This gets skipped for the same reason that the doctest in a literal block +# gets skipped. +def rst_directive_skipped_doctest(): + """ + .. code-block:: python + + >>> cool_stuff( 1 ) + + Done. + """ + pass + + +############################################################################### +# Markdown CODE EXAMPLES +# +# This section shows examples of docstrings that contain code snippets in +# Markdown fenced code blocks. +# +# See: https://spec.commonmark.org/0.30/#fenced-code-blocks +############################################################################### + + +def markdown_simple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_simple_continued(): + """ + Do cool stuff. + + ```python + def cool_stuff(x): + print(f"hi {x}") + ``` + + Done. + """ + pass + + +# Tests that unlabeled Markdown fenced code blocks are assumed to be Python. +def markdown_unlabeled(): + """ + Do cool stuff. + + ``` + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that fenced code blocks using tildes work. +def markdown_tildes(): + """ + Do cool stuff. + + ~~~py + cool_stuff(1) + ~~~ + + Done. + """ + pass + + +# Tests that a longer closing fence is just fine and dandy. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + `````` + + Done. + """ + pass + + +# Tests that an invalid closing fence is treated as invalid. +# +# We embed it into a docstring so that the surrounding Python +# remains valid. +def markdown_longer_closing_fence(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ''' + ```invalid + ''' + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Tests that one can nest fenced code blocks by using different numbers of +# backticks. +def markdown_nested_fences(): + """ + Do cool stuff. + + `````` + do_something( + ''' + ``` + did i trick you? + ``` + ''' + ) + `````` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring. When it's only empty lines, those are passed into the formatter +# and thus stripped. +def markdown_unclosed_empty_lines(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the second to last line of the +# docstring. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + """ + pass + + +# Tests that an unclosed block with one extra line at the end is treated +# correctly. As per the CommonMark spec, an unclosed fenced code block contains +# everything following the opening fences. Since formatting the code snippet +# trims lines, the last empty line is removed here. +def markdown_second_to_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +# Tests that we can end the block on the actual last line of the docstring. +def markdown_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ```""" + pass + + +# Tests that an unclosed block that ends on the last line of a docstring +# is handled correctly. +def markdown_unclosed_actually_last(): + """ + Do cool stuff. + + ```py + cool_stuff(1)""" + pass + + +def markdown_with_blank_lines(): + """ + Do cool stuff. + + ```py + def cool_stuff(x): + print(f"hi {x}") + + + def other_stuff(y): + print(y) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_4spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +def markdown_first_line_indent_uses_tabs_8spaces_multiple(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_first_line_tab_second_line_spaces(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_odd_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + cool_stuff(2) + ``` + + Done. + """ + pass + + +# Extra blanks should be *not* be preserved (unlike reST) because they are part +# of the code snippet (per CommonMark spec), and thus get trimmed as part of +# code formatting. +def markdown_extra_blanks(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + ``` + + Done. + """ + pass + + +# A block can contain many empty lines within it. +def markdown_extra_blanks_in_snippet(): + """ + Do cool stuff. + + ```py + cool_stuff(1) + + + cool_stuff(2) + ``` + + Done. + """ + pass + + +def markdown_weird_closing(): + """ + Code block with weirdly placed closing fences. + + ```python + cool_stuff(1) + ``` + # The above fences look like it shouldn't close the block, but we + # allow it to. The fences below re-open a block (until the end of + # the docstring), but it's invalid Python and thus doesn't get + # reformatted. + a = 10 + ``` + + Now the code block is closed + """ + pass + + +def markdown_over_indented(): + """ + A docstring + over intended + ```python + print(5) + ``` + """ + pass + + +# This tests that we can have additional text after the language specifier. +def markdown_additional_info_string(): + """ + Do cool stuff. + + ```python tab="plugin.py" + cool_stuff(1) + ``` + + Done. + """ + pass + + +# Tests that an unclosed block gobbles up everything remaining in the +# docstring, even if it isn't valid Python. Since it isn't valid Python, +# reformatting fails and the entire thing is skipped. +def markdown_skipped_unclosed_non_python(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + + I forgot to close the code block, and this is definitely not + Python. So nothing here gets formatted. + """ + pass + + +# This has a Python snippet with a docstring that contains a closing fence. +# This splits the embedded docstring and makes the overall snippet invalid. +def markdown_skipped_accidental_closure(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ''' + ``` + ''' + ``` + + Done. + """ + pass + + +# When a line is unindented all the way out before the standard indent of the +# docstring, the code reformatting ends up interacting poorly with the standard +# docstring whitespace normalization logic. This is probably a bug, and we +# should probably treat the Markdown block as valid, but for now, we detect +# the unindented line and declare the block as invalid and thus do no code +# reformatting. +# +# FIXME: Fixing this (if we think it's a bug) probably requires refactoring the +# docstring whitespace normalization to be aware of code snippets. Or perhaps +# plausibly, to do normalization *after* code snippets have been formatted. +def markdown_skipped_unindented_completely(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This test is fallout from treating fenced code blocks with unindented lines +# as invalid. We probably should treat this as a valid block. Indeed, if we +# remove the logic that makes the `markdown_skipped_unindented_completely` test +# pass, then this code snippet will get reformatted correctly. +def markdown_skipped_unindented_somewhat(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +# This tests that if a Markdown block contains a line that has less of an +# indent than another line. +# +# There is some judgment involved in what the right behavior is here. We +# could "normalize" the indentation so that the minimum is the indent of the +# opening fence line. If we did that here, then the code snippet would become +# valid and format as Python. But at time of writing, we don't, which leads to +# inconsistent indentation and thus invalid Python. +def markdown_skipped_unindented_with_inconsistent_indentation(): + """ + Do cool stuff. + + ```py + cool_stuff( 1 ) + cool_stuff( 2 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_doctest(): + """ + Do cool stuff. + + ```py + >>> cool_stuff( 1 ) + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_literal(): + """ + Do cool stuff. + + ```py + And do this:: + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass + + +def markdown_skipped_rst_directive(): + """ + Do cool stuff. + + ```py + .. code-block:: python + + cool_stuff( 1 ) + + ``` + + Done. + """ + pass +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap new file mode 100644 index 0000000000000..9f7fd5b9ac5b7 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap @@ -0,0 +1,45 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py +--- +## Input +```python +def doctest_line_ending(): + """ + Do cool stuff. + >>> def foo( x ): + ... print( x ) + ... + ... print( x ) + """ + pass +``` + +## Outputs +### Output 1 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = CarriageReturnLineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +def doctest_line_ending(): + """ + Do cool stuff. + >>> def foo(x): + ... print(x) + ... + ... print(x) + """ + pass +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_dynamic_line_width.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_dynamic_line_width.py.snap new file mode 100644 index 0000000000000..1bab5f433b52a --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_dynamic_line_width.py.snap @@ -0,0 +1,1875 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_dynamic_line_width.py +--- +## Input +```python +def simple(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + ``` + + Done. + """ + pass + + +# Like simple, but we double everything up to ensure the indent level is +# tracked correctly. +def repeated(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + + class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) + ``` + + Done. + """ + pass + + +# Like simple, but we make one line exactly one character longer than the limit +# (for 4-space indents) and make sure it gets wrapped. +def barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678) + return 5 + self.x = doit( 5 ) + ``` + + Done. + """ + pass + + +# This tests that if the code block is unindented, that it gets indented and +# the dynamic line width setting is applied correctly. +def unindented(): + """ + First line. + +```py +class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + self.x = doit( 5 ) +``` + + Done. + """ + pass + + +# Like unindented, but contains a `print` line where it just barely exceeds the +# globally configured line width *after* its indentation has been corrected. +def unindented_barely_exceeds_limit(): + """ + First line. + +```py +class Abcdefghijklmopqrstuvwxyz(Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5): + def abcdefghijklmnopqrstuvwxyz(self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + def abcdefghijklmnopqrstuvwxyz(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678) + return 5 + self.x = doit( 5 ) +``` + + Done. + """ + pass + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent1(): + """ + Docstring example containing a class. + + Examples + -------- + >>> @pl.api.register_dataframe_namespace("split") + ... class SplitFrame: + ... def __init__(self, df: pl.DataFrame): + ... self._df = df + ... + ... def by_first_letter_of_column_values(self, col: str) -> list[pl.DataFrame]: + ... return [ + ... self._df.filter(pl.col(col).str.starts_with(c)) + ... for c in sorted( + ... set(df.select(pl.col(col).str.slice(0, 1)).to_series()) + ... ) + ... ] + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +class DoctestExtraIndent2: + def example2(): + """ + Regular docstring of class method. + + Examples + -------- + >>> df = pl.DataFrame( + ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} + ... ) + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent3(): + """ + Pragma comment. + + Examples + -------- + >>> af1, af2, af3 = pl.align_frames( + ... df1, df2, df3, on="dt" + ... ) # doctest: +IGNORE_RESULT + """ +``` + +## Outputs +### Output 1 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +def simple(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like simple, but we double everything up to ensure the indent level is +# tracked correctly. +def repeated(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like simple, but we make one line exactly one character longer than the limit +# (for 4-space indents) and make sure it gets wrapped. +def barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678 + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# This tests that if the code block is unindented, that it gets indented and +# the dynamic line width setting is applied correctly. +def unindented(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like unindented, but contains a `print` line where it just barely exceeds the +# globally configured line width *after* its indentation has been corrected. +def unindented_barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678 + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent1(): + """ + Docstring example containing a class. + + Examples + -------- + >>> @pl.api.register_dataframe_namespace("split") + ... class SplitFrame: + ... def __init__(self, df: pl.DataFrame): + ... self._df = df + ... + ... def by_first_letter_of_column_values(self, col: str) -> list[pl.DataFrame]: + ... return [ + ... self._df.filter(pl.col(col).str.starts_with(c)) + ... for c in sorted( + ... set(df.select(pl.col(col).str.slice(0, 1)).to_series()) + ... ) + ... ] + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +class DoctestExtraIndent2: + def example2(): + """ + Regular docstring of class method. + + Examples + -------- + >>> df = pl.DataFrame( + ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} + ... ) + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent3(): + """ + Pragma comment. + + Examples + -------- + >>> af1, af2, af3 = pl.align_frames( + ... df1, df2, df3, on="dt" + ... ) # doctest: +IGNORE_RESULT + """ +``` + + +### Output 2 +``` +indent-style = space +line-width = 88 +indent-width = 2 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +def simple(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like simple, but we double everything up to ensure the indent level is +# tracked correctly. +def repeated(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like simple, but we make one line exactly one character longer than the limit +# (for 4-space indents) and make sure it gets wrapped. +def barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# This tests that if the code block is unindented, that it gets indented and +# the dynamic line width setting is applied correctly. +def unindented(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like unindented, but contains a `print` line where it just barely exceeds the +# globally configured line width *after* its indentation has been corrected. +def unindented_barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent1(): + """ + Docstring example containing a class. + + Examples + -------- + >>> @pl.api.register_dataframe_namespace("split") + ... class SplitFrame: + ... def __init__(self, df: pl.DataFrame): + ... self._df = df + ... + ... def by_first_letter_of_column_values(self, col: str) -> list[pl.DataFrame]: + ... return [ + ... self._df.filter(pl.col(col).str.starts_with(c)) + ... for c in sorted(set(df.select(pl.col(col).str.slice(0, 1)).to_series())) + ... ] + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +class DoctestExtraIndent2: + def example2(): + """ + Regular docstring of class method. + + Examples + -------- + >>> df = pl.DataFrame({"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]}) + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent3(): + """ + Pragma comment. + + Examples + -------- + >>> af1, af2, af3 = pl.align_frames(df1, df2, df3, on="dt") # doctest: +IGNORE_RESULT + """ +``` + + +### Output 3 +``` +indent-style = tab +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +def simple(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like simple, but we double everything up to ensure the indent level is +# tracked correctly. +def repeated(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like simple, but we make one line exactly one character longer than the limit +# (for 4-space indents) and make sure it gets wrapped. +def barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678 + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# This tests that if the code block is unindented, that it gets indented and +# the dynamic line width setting is applied correctly. +def unindented(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print(abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a567) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like unindented, but contains a `print` line where it just barely exceeds the +# globally configured line width *after* its indentation has been corrected. +def unindented_barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + def abcdefghijklmnopqrstuvwxyz( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4 + ): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print( + abc, ddef, ghi, jkl, mno, pqr, stu, vwx, yz, a1, a2, a3, a4, a5678 + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent1(): + """ + Docstring example containing a class. + + Examples + -------- + >>> @pl.api.register_dataframe_namespace("split") + ... class SplitFrame: + ... def __init__(self, df: pl.DataFrame): + ... self._df = df + ... + ... def by_first_letter_of_column_values(self, col: str) -> list[pl.DataFrame]: + ... return [ + ... self._df.filter(pl.col(col).str.starts_with(c)) + ... for c in sorted( + ... set(df.select(pl.col(col).str.slice(0, 1)).to_series()) + ... ) + ... ] + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +class DoctestExtraIndent2: + def example2(): + """ + Regular docstring of class method. + + Examples + -------- + >>> df = pl.DataFrame( + ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} + ... ) + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent3(): + """ + Pragma comment. + + Examples + -------- + >>> af1, af2, af3 = pl.align_frames( + ... df1, df2, df3, on="dt" + ... ) # doctest: +IGNORE_RESULT + """ +``` + + +### Output 4 +``` +indent-style = tab +line-width = 88 +indent-width = 8 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +def simple(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like simple, but we double everything up to ensure the indent level is +# tracked correctly. +def repeated(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + self, + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + + + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + self, + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like simple, but we make one line exactly one character longer than the limit +# (for 4-space indents) and make sure it gets wrapped. +def barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a5678, + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# This tests that if the code block is unindented, that it gets indented and +# the dynamic line width setting is applied correctly. +def unindented(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is just one character shy of + # tripping the default line width of 88. So it should not be + # wrapped. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a567, + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# Like unindented, but contains a `print` line where it just barely exceeds the +# globally configured line width *after* its indentation has been corrected. +def unindented_barely_exceeds_limit(): + """ + First line. + + ```py + class Abcdefghijklmopqrstuvwxyz( + Abc, Def, Ghi, Jkl, Mno, Pqr, Stu, Vwx, Yz, A1, A2, A3, A4, A5 + ): + def abcdefghijklmnopqrstuvwxyz( + self, + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + def abcdefghijklmnopqrstuvwxyz( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + ): + # For 4 space indents, this is 89 columns, which is one + # more than the limit. Therefore, it should get wrapped for + # indent_width >= 4. + print( + abc, + ddef, + ghi, + jkl, + mno, + pqr, + stu, + vwx, + yz, + a1, + a2, + a3, + a4, + a5678, + ) + return 5 + + self.x = doit(5) + ``` + + Done. + """ + pass + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent1(): + """ + Docstring example containing a class. + + Examples + -------- + >>> @pl.api.register_dataframe_namespace("split") + ... class SplitFrame: + ... def __init__(self, df: pl.DataFrame): + ... self._df = df + ... + ... def by_first_letter_of_column_values( + ... self, col: str + ... ) -> list[pl.DataFrame]: + ... return [ + ... self._df.filter(pl.col(col).str.starts_with(c)) + ... for c in sorted( + ... set( + ... df.select( + ... pl.col(col).str.slice(0, 1) + ... ).to_series() + ... ) + ... ) + ... ] + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +class DoctestExtraIndent2: + def example2(): + """ + Regular docstring of class method. + + Examples + -------- + >>> df = pl.DataFrame( + ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} + ... ) + """ + + +# See: https://github.com/astral-sh/ruff/issues/9126 +def doctest_extra_indent3(): + """ + Pragma comment. + + Examples + -------- + >>> af1, af2, af3 = pl.align_frames( + ... df1, df2, df3, on="dt" + ... ) # doctest: +IGNORE_RESULT + """ +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__binary.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__binary.py.snap index e245378863ad4..1d59b5b13a1bc 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__binary.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__binary.py.snap @@ -325,6 +325,18 @@ expected_content = ( ) ) +# Skip FString content when determining whether to omit optional parentheses or not.0 +# The below expression should be parenthesized because it ends with an fstring and starts with a name. +# (Call expressions at the beginning don't count as parenthesized because they don't start with parens). +assert ( + format.format_event(spec) + == f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})' +) +# Avoid parentheses for this example because it starts with a tuple expression. +assert ( + (spec, format) + == f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})' +) rowuses = [(1 << j) | # column ordinal (1 << (n + i-j + n-1)) | # NW-SE ordinal @@ -790,6 +802,18 @@ expected_content = ( ) ) +# Skip FString content when determining whether to omit optional parentheses or not.0 +# The below expression should be parenthesized because it ends with an fstring and starts with a name. +# (Call expressions at the beginning don't count as parenthesized because they don't start with parens). +assert ( + format.format_event(spec) + == f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})' +) +# Avoid parentheses for this example because it starts with a tuple expression. +assert ( + spec, + format, +) == f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})' rowuses = [ (1 << j) # column ordinal diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap index 1e8baabd73238..b741654c94c4a 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap @@ -129,12 +129,15 @@ test_particular = [ ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -278,12 +281,15 @@ test_particular = [ ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Single -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Single +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__hug.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__hug.py.snap new file mode 100644 index 0000000000000..f9a4ca0ba5be8 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__hug.py.snap @@ -0,0 +1,752 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/hug.py +--- +## Input +```python +# Preview style: hug brackets to call parentheses. +func([1, 2, 3,]) + +func( # comment +[1, 2, 3,]) + +func( + # comment +[1, 2, 3,]) + +func([1, 2, 3,] # comment +) + +func([1, 2, 3,] + # comment +) + +func([ # comment + 1, 2, 3,] +) + +func(([1, 2, 3,])) + + +func( + ( + 1, + 2, + 3, + ) +) + +# Ensure that comprehensions hug too. +func([(x, y,) for (x, y) in z]) + +# Ensure that dictionaries hug too. +func({1: 2, 3: 4, 5: 6,}) + +# Ensure that the same behavior is applied to parenthesized expressions. +([1, 2, 3,]) + +( # comment + [1, 2, 3,]) + +( + [ # comment + 1, 2, 3,]) + +# Ensure that starred arguments are also hugged. +foo( + *[ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + * # comment + [ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + **[ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + ** # comment + [ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +# Ensure that multi-argument calls are _not_ hugged. +func([1, 2, 3,], bar) + +func([(x, y,) for (x, y) in z], bar) + +# Ensure that return type annotations (which use `parenthesize_if_expands`) are also hugged. +def func() -> [1, 2, 3,]: + pass + +def func() -> ([1, 2, 3,]): + pass + +def func() -> ([1, 2, 3,]): + pass + +def func() -> ( # comment + [1, 2, 3,]): + pass + +def func() -> ( + [1, 2, 3,] # comment +): + pass + +def func() -> ( + [1, 2, 3,] + # comment +): + pass + +# Ensure that nested lists are hugged. +func([ + [ + 1, + 2, + 3, + ] +]) + + +func([ + # comment + [ + 1, + 2, + 3, + ] +]) + +func([ + [ + 1, + 2, + 3, + ] + # comment +]) + +func([ + [ # comment + 1, + 2, + 3, + ] +]) + + +func([ # comment + [ + 1, + 2, + 3, + ] +]) +``` + +## Output +```python +# Preview style: hug brackets to call parentheses. +func( + [ + 1, + 2, + 3, + ] +) + +func( # comment + [ + 1, + 2, + 3, + ] +) + +func( + # comment + [ + 1, + 2, + 3, + ] +) + +func( + [ + 1, + 2, + 3, + ] # comment +) + +func( + [ + 1, + 2, + 3, + ] + # comment +) + +func( + [ # comment + 1, + 2, + 3, + ] +) + +func( + ( + [ + 1, + 2, + 3, + ] + ) +) + + +func( + ( + 1, + 2, + 3, + ) +) + +# Ensure that comprehensions hug too. +func( + [ + ( + x, + y, + ) + for (x, y) in z + ] +) + +# Ensure that dictionaries hug too. +func( + { + 1: 2, + 3: 4, + 5: 6, + } +) + +# Ensure that the same behavior is applied to parenthesized expressions. +( + [ + 1, + 2, + 3, + ] +) + +( # comment + [ + 1, + 2, + 3, + ] +) + +( + [ # comment + 1, + 2, + 3, + ] +) + +# Ensure that starred arguments are also hugged. +foo( + *[ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + # comment + *[ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + **[ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +foo( + # comment + **[ + a_long_function_name(a_long_variable_name) + for a_long_variable_name in some_generator + ] +) + +# Ensure that multi-argument calls are _not_ hugged. +func( + [ + 1, + 2, + 3, + ], + bar, +) + +func( + [ + ( + x, + y, + ) + for (x, y) in z + ], + bar, +) + + +# Ensure that return type annotations (which use `parenthesize_if_expands`) are also hugged. +def func() -> ( + [ + 1, + 2, + 3, + ] +): + pass + + +def func() -> ( + [ + 1, + 2, + 3, + ] +): + pass + + +def func() -> ( + [ + 1, + 2, + 3, + ] +): + pass + + +def func() -> ( # comment + [ + 1, + 2, + 3, + ] +): + pass + + +def func() -> ( + [ + 1, + 2, + 3, + ] # comment +): + pass + + +def func() -> ( + [ + 1, + 2, + 3, + ] + # comment +): + pass + + +# Ensure that nested lists are hugged. +func( + [ + [ + 1, + 2, + 3, + ] + ] +) + + +func( + [ + # comment + [ + 1, + 2, + 3, + ] + ] +) + +func( + [ + [ + 1, + 2, + 3, + ] + # comment + ] +) + +func( + [ + [ # comment + 1, + 2, + 3, + ] + ] +) + + +func( + [ # comment + [ + 1, + 2, + 3, + ] + ] +) +``` + + +## Preview changes +```diff +--- Stable ++++ Preview +@@ -1,11 +1,9 @@ + # Preview style: hug brackets to call parentheses. +-func( +- [ +- 1, +- 2, +- 3, +- ] +-) ++func([ ++ 1, ++ 2, ++ 3, ++]) + + func( # comment + [ +@@ -41,61 +39,47 @@ + # comment + ) + +-func( +- [ # comment +- 1, +- 2, +- 3, +- ] +-) ++func([ # comment ++ 1, ++ 2, ++ 3, ++]) + +-func( +- ( +- [ +- 1, +- 2, +- 3, +- ] +- ) +-) ++func(([ ++ 1, ++ 2, ++ 3, ++])) + + +-func( +- ( +- 1, +- 2, +- 3, +- ) +-) ++func(( ++ 1, ++ 2, ++ 3, ++)) + + # Ensure that comprehensions hug too. +-func( +- [ +- ( +- x, +- y, +- ) +- for (x, y) in z +- ] +-) ++func([ ++ ( ++ x, ++ y, ++ ) ++ for (x, y) in z ++]) + + # Ensure that dictionaries hug too. +-func( +- { +- 1: 2, +- 3: 4, +- 5: 6, +- } +-) ++func({ ++ 1: 2, ++ 3: 4, ++ 5: 6, ++}) + + # Ensure that the same behavior is applied to parenthesized expressions. +-( +- [ +- 1, +- 2, +- 3, +- ] +-) ++([ ++ 1, ++ 2, ++ 3, ++]) + + ( # comment + [ +@@ -105,21 +89,17 @@ + ] + ) + +-( +- [ # comment +- 1, +- 2, +- 3, +- ] +-) ++([ # comment ++ 1, ++ 2, ++ 3, ++]) + + # Ensure that starred arguments are also hugged. +-foo( +- *[ +- a_long_function_name(a_long_variable_name) +- for a_long_variable_name in some_generator +- ] +-) ++foo(*[ ++ a_long_function_name(a_long_variable_name) ++ for a_long_variable_name in some_generator ++]) + + foo( + # comment +@@ -129,12 +109,10 @@ + ] + ) + +-foo( +- **[ +- a_long_function_name(a_long_variable_name) +- for a_long_variable_name in some_generator +- ] +-) ++foo(**[ ++ a_long_function_name(a_long_variable_name) ++ for a_long_variable_name in some_generator ++]) + + foo( + # comment +@@ -167,33 +145,27 @@ + + + # Ensure that return type annotations (which use `parenthesize_if_expands`) are also hugged. +-def func() -> ( +- [ +- 1, +- 2, +- 3, +- ] +-): ++def func() -> ([ ++ 1, ++ 2, ++ 3, ++]): + pass + + +-def func() -> ( +- [ +- 1, +- 2, +- 3, +- ] +-): ++def func() -> ([ ++ 1, ++ 2, ++ 3, ++]): + pass + + +-def func() -> ( +- [ +- 1, +- 2, +- 3, +- ] +-): ++def func() -> ([ ++ 1, ++ 2, ++ 3, ++]): + pass + + +@@ -229,56 +201,46 @@ + + + # Ensure that nested lists are hugged. +-func( ++func([ + [ +- [ +- 1, +- 2, +- 3, +- ] ++ 1, ++ 2, ++ 3, + ] +-) ++]) + + +-func( ++func([ ++ # comment + [ +- # comment +- [ +- 1, +- 2, +- 3, +- ] ++ 1, ++ 2, ++ 3, + ] +-) ++]) + +-func( ++func([ + [ +- [ +- 1, +- 2, +- 3, +- ] +- # comment ++ 1, ++ 2, ++ 3, + ] +-) ++ # comment ++]) + +-func( +- [ +- [ # comment +- 1, +- 2, +- 3, +- ] ++func([ ++ [ # comment ++ 1, ++ 2, ++ 3, + ] +-) ++]) + + +-func( +- [ # comment +- [ +- 1, +- 2, +- 3, +- ] ++func([ # comment ++ [ ++ 1, ++ 2, ++ 3, + ] +-) ++]) +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__optional_parentheses_comments.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__optional_parentheses_comments.py.snap index 4279cd03f29db..23c95ef3a2756 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__optional_parentheses_comments.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__optional_parentheses_comments.py.snap @@ -421,4 +421,44 @@ def test6(): ``` +## Preview changes +```diff +--- Stable ++++ Preview +@@ -72,13 +72,13 @@ + ## Breaking left + + # Should break `[a]` first +-____[ +- a +-] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvv # c ++____[a] = ( ++ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvv # c ++) + +-____[ +- a +-] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvv # cc ++____[a] = ( ++ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvv # cc ++) + + ( + # some weird comments +@@ -136,9 +136,9 @@ + # 89 characters parenthesized (collapse) + ____a: a = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvv # c + +-_a: a[ +- b +-] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvv # c ++_a: a[b] = ( ++ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvv # c ++) + + ## Augmented Assign + +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__split_empty_brackets.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__split_empty_brackets.py.snap index 810964acc19a2..2c9fb1d380816 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__split_empty_brackets.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__split_empty_brackets.py.snap @@ -194,4 +194,24 @@ response = await sync_to_async( ``` +## Preview changes +```diff +--- Stable ++++ Preview +@@ -62,9 +62,9 @@ + 1 + }.unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold() + +-ct_match = ([]).unicodedata.normalize("NFKC", s1).casefold() == ( +- [] +-).unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold() ++ct_match = ([]).unicodedata.normalize( ++ "NFKC", s1 ++).casefold() == ([]).unicodedata.normalize("NFKCNFKCNFKCNFKCNFKC", s2).casefold() + + return await self.http_client.fetch( + f"http://127.0.0.1:{self.port}{path}", +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap index 09830dae06dfa..306a10a49f9fe 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap @@ -144,12 +144,15 @@ trailing_preferred_quote_texts = [''' "''', ''' ""''', ''' """''', ''' """"'''] ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -317,12 +320,15 @@ trailing_preferred_quote_texts = [''' "''', ''' ""''', ''' """''', ''' """"'''] ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Single -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Single +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap index 8cca1bee8815a..2c5ce6935feec 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap @@ -28,12 +28,15 @@ def test(): ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -61,12 +64,15 @@ def test(): ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 2 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 2 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap index 87873bcc8a203..f1db6d7a8bfdc 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap @@ -9,12 +9,15 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -23,12 +26,15 @@ preview = Disabled ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 1 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 1 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -37,12 +43,15 @@ preview = Disabled ### Output 3 ``` -indent-style = tab -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = tab +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap index 619cb49876d8d..7ff04c9571b70 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap @@ -24,12 +24,15 @@ not_fixed ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -54,12 +57,15 @@ not_fixed ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 2 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 2 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -84,12 +90,15 @@ not_fixed ### Output 3 ``` -indent-style = tab -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = tab +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@parentheses__opening_parentheses_comment_value.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@parentheses__opening_parentheses_comment_value.py.snap index 4c226dd8c3d9a..2dc81368793b1 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@parentheses__opening_parentheses_comment_value.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@parentheses__opening_parentheses_comment_value.py.snap @@ -253,7 +253,7 @@ except ( # d 9 def e1( # e 1 - x + x, ): pass diff --git a/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap index f7167deef5e09..fdedcce512dd8 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap @@ -75,12 +75,15 @@ def f(): ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -154,12 +157,15 @@ def f(): ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Enabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Enabled ``` ```python @@ -198,17 +204,17 @@ class RemoveNewlineBeforeClassDocstring: def f(): """Black's `Preview.prefer_splitting_right_hand_side_of_assignments`""" - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[ - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - ] = cccccccc.ccccccccccccc.cccccccc + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ( + cccccccc.ccccccccccccc.cccccccc + ) - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[ - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - ] = cccccccc.ccccccccccccc().cccccccc + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ( + cccccccc.ccccccccccccc().cccccccc + ) - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[ - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - ] = cccccccc.ccccccccccccc(d).cccccccc + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ( + cccccccc.ccccccccccccc(d).cccccccc + ) aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ( cccccccc.ccccccccccccc(d).cccccccc + e @@ -222,12 +228,12 @@ def f(): + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ) - self._cache: dict[ - DependencyCacheKey, list[list[DependencyPackage]] - ] = collections.defaultdict(list) - self._cached_dependencies_by_level: dict[ - int, list[DependencyCacheKey] - ] = collections.defaultdict(list) + self._cache: dict[DependencyCacheKey, list[list[DependencyPackage]]] = ( + collections.defaultdict(list) + ) + self._cached_dependencies_by_level: dict[int, list[DependencyCacheKey]] = ( + collections.defaultdict(list) + ) ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap new file mode 100644 index 0000000000000..ed5c09022e14e --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap @@ -0,0 +1,273 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.py +--- +## Input +```python +'single' +"double" +r'r single' +r"r double" +f'f single' +f"f double" +fr'fr single' +fr"fr double" +rf'rf single' +rf"rf double" +b'b single' +b"b double" +rb'rb single' +rb"rb double" +br'br single' +br"br double" + +'''single triple''' +"""double triple""" +r'''r single triple''' +r"""r double triple""" +f'''f single triple''' +f"""f double triple""" +fr'''fr single triple''' +fr"""fr double triple""" +rf'''rf single triple''' +rf"""rf double triple""" +b'''b single triple''' +b"""b double triple""" +rb'''rb single triple''' +rb"""rb double triple""" +br'''br single triple''' +br"""br double triple""" + +'single1' 'single2' +'single1' "double2" +"double1" 'single2' +"double1" "double2" + +def docstring_single_triple(): + '''single triple''' + +def docstring_double_triple(): + """double triple""" + +def docstring_double(): + "double triple" + +def docstring_single(): + 'single' +``` + +## Outputs +### Output 1 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Single +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +'single' +'double' +r'r single' +r'r double' +f'f single' +f'f double' +rf'fr single' +rf'fr double' +rf'rf single' +rf'rf double' +b'b single' +b'b double' +rb'rb single' +rb'rb double' +rb'br single' +rb'br double' + +"""single triple""" +"""double triple""" +r"""r single triple""" +r"""r double triple""" +f"""f single triple""" +f"""f double triple""" +rf"""fr single triple""" +rf"""fr double triple""" +rf"""rf single triple""" +rf"""rf double triple""" +b"""b single triple""" +b"""b double triple""" +rb"""rb single triple""" +rb"""rb double triple""" +rb"""br single triple""" +rb"""br double triple""" + +'single1' 'single2' +'single1' 'double2' +'double1' 'single2' +'double1' 'double2' + + +def docstring_single_triple(): + """single triple""" + + +def docstring_double_triple(): + """double triple""" + + +def docstring_double(): + "double triple" + + +def docstring_single(): + "single" +``` + + +### Output 2 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +"single" +"double" +r"r single" +r"r double" +f"f single" +f"f double" +rf"fr single" +rf"fr double" +rf"rf single" +rf"rf double" +b"b single" +b"b double" +rb"rb single" +rb"rb double" +rb"br single" +rb"br double" + +"""single triple""" +"""double triple""" +r"""r single triple""" +r"""r double triple""" +f"""f single triple""" +f"""f double triple""" +rf"""fr single triple""" +rf"""fr double triple""" +rf"""rf single triple""" +rf"""rf double triple""" +b"""b single triple""" +b"""b double triple""" +rb"""rb single triple""" +rb"""rb double triple""" +rb"""br single triple""" +rb"""br double triple""" + +"single1" "single2" +"single1" "double2" +"double1" "single2" +"double1" "double2" + + +def docstring_single_triple(): + """single triple""" + + +def docstring_double_triple(): + """double triple""" + + +def docstring_double(): + "double triple" + + +def docstring_single(): + "single" +``` + + +### Output 3 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Preserve +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled +``` + +```python +'single' +"double" +r'r single' +r"r double" +f'f single' +f"f double" +rf'fr single' +rf"fr double" +rf'rf single' +rf"rf double" +b'b single' +b"b double" +rb'rb single' +rb"rb double" +rb'br single' +rb"br double" + +"""single triple""" +"""double triple""" +r"""r single triple""" +r"""r double triple""" +f"""f single triple""" +f"""f double triple""" +rf"""fr single triple""" +rf"""fr double triple""" +rf"""rf single triple""" +rf"""rf double triple""" +b"""b single triple""" +b"""b double triple""" +rb"""rb single triple""" +rb"""rb double triple""" +rb"""br single triple""" +rb"""br double triple""" + +'single1' 'single2' +'single1' "double2" +"double1" 'single2' +"double1" "double2" + + +def docstring_single_triple(): + """single triple""" + + +def docstring_double_triple(): + """double triple""" + + +def docstring_double(): + "double triple" + + +def docstring_single(): + "single" +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap index 1434f6a964a93..83b67689f467f 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap @@ -42,12 +42,15 @@ with (a,): # magic trailing comma ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -95,12 +98,15 @@ with ( ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Ignore -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Ignore +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap index 69490f3caf53c..191b6d141bb42 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap @@ -67,4 +67,24 @@ class DefaultRunner: ``` +## Preview changes +```diff +--- Stable ++++ Preview +@@ -7,9 +7,9 @@ + Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() + ) + +-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: ( +- Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +-) = Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() ++bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = ( ++ Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() ++) + + JSONSerializable: TypeAlias = ( + "str | int | float | bool | None | list | tuple | JSONMapping" +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__assign.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__assign.py.snap index 075824ab64f32..b78a7687774c4 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__assign.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__assign.py.snap @@ -73,6 +73,15 @@ def main() -> None: db_request.POST["name"] ) )[0] + + +c = b[dddddd, aaaaaa] = ( + a[ + aaaaaaa, + bbbbbbbbbbbbbbbbbbb + ] + # comment +) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` ## Output @@ -151,6 +160,48 @@ def main() -> None: db_request.POST["name"] ) )[0] + + +c = b[dddddd, aaaaaa] = ( + a[aaaaaaa, bbbbbbbbbbbbbbbbbbb] + # comment +) = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` + + +## Preview changes +```diff +--- Stable ++++ Preview +@@ -1,7 +1,5 @@ + # break left hand side +-a1akjdshflkjahdslkfjlasfdahjlfds = ( +- bakjdshflkjahdslkfjlasfdahjlfds +-) = ( ++a1akjdshflkjahdslkfjlasfdahjlfds = bakjdshflkjahdslkfjlasfdahjlfds = ( + cakjdshflkjahdslkfjlasfdahjlfds + ) = kjaödkjaföjfahlfdalfhaöfaöfhaöfha = fkjaödkjaföjfahlfdalfhaöfaöfhaöfha = g = 3 + +@@ -9,15 +7,13 @@ + a2 = b2 = 2 + + # Break the last element +-a = ( +- asdf +-) = ( ++a = asdf = ( + fjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfal + ) = 1 + +-aa = [ +- bakjdshflkjahdslkfjlasfdahjlfds +-] = dddd = ddd = fkjaödkjaföjfahlfdalfhaöfaöfhaöfha = g = [3] ++aa = [bakjdshflkjahdslkfjlasfdahjlfds] = dddd = ddd = ( ++ fkjaödkjaföjfahlfdalfhaöfaöfhaöfha ++) = g = [3] + + aa = [] = dddd = ddd = fkjaödkjaföjfahlfdalfhaöfaöfhaöfha = g = [3] + ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__assignment_split_value_first.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__assignment_split_value_first.py.snap new file mode 100644 index 0000000000000..38e2e31a44354 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__assignment_split_value_first.py.snap @@ -0,0 +1,457 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assignment_split_value_first.py +--- +## Input +```python +####### +# Unsplittable target and value + +# Only parenthesize the value if it makes it fit, otherwise avoid parentheses. +b = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee + +bbbbbbbbbbbbbbbb = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvv + +# Avoid parenthesizing the value even if the target exceeds the configured width +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = bbb + + +############ +# Splittable targets + +# Does not double-parenthesize tuples +( + first_item, + second_item, +) = some_looooooooong_module.some_loooooog_function_name( + first_argument, second_argument, third_argument +) + + +# Preserve parentheses around the first target +( + req["ticket"]["steps"]["step"][0]["tasks"]["task"]["fields"]["field"][ + "access_request" + ]["destinations"]["destination"][0]["ip_address"] +) = dst + +# Augmented assignment +req["ticket"]["steps"]["step"][0]["tasks"]["task"]["fields"]["field"][ + "access_request" +] += dst + +# Always parenthesize the value if it avoids splitting the target, regardless of the value's width. +_a: a[aaaa] = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv +) + +##### +# Avoid parenthesizing the value if the expression right before the `=` splits to avoid an unnecessary pair of parentheses + +# The type annotation is guaranteed to split because it is too long. +_a: a[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv +] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv + +# The target is too long +( + aaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv + +# The target splits because of a magic trailing comma +( + a, + b, +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +# The targets split because of a comment +( + # leading + a +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +( + a + # trailing +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +( + a, # nested + b +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +####### +# Multi targets + +# Black always parenthesizes the right if using multiple targets regardless if the parenthesized value exceeds the +# the configured line width or not +aaaa = bbbbbbbbbbbbbbbb = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee +) + +# Black does parenthesize the target if the target itself exceeds the line width and only parenthesizes +# the values if it makes it fit. +# The second target is too long to ever fit into the configured line width. +aaaa = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddd +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee + +# Does also apply for other multi target assignments, as soon as a single target exceeds the configured +# width +aaaaaa = a["aaa"] = bbbbb[aa, bbb, cccc] = dddddddddd = eeeeee = ( + fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + +###################### +# Call expressions: +# For unsplittable targets: Parenthesize the call expression if it makes it fit. +# +# For splittable targets: +# Only parenthesize a call expression if the parens of the call don't fit on the same line +# as the target. Don't parenthesize the call expression if the target (or annotation) right before +# splits. + +# Don't parenthesize the function call if the left is unsplittable. +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = a.b.function( + arg1, arg2, arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], + arg1, + [1, 2, 3], + arg2, + [1, 2, 3], + arg3, + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd, + eeeeeeeeeeeeee, +) + +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = ( + function() +) +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = ( + a.b.function(arg1, arg2, arg3) +) +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function() +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function( + [1, 2, 3], + arg1, + [1, 2, 3], + arg2, + [1, 2, 3], + arg3, + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd, + eeeeeeeeeeeeee, +) + +####### Fluent call expressions +# Uses the regular `Multiline` layout where the entire `value` gets parenthesized +# if it doesn't fit on the line. +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use = ( + function().b().c([1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3) +) + + +####### +# Test comment inlining +value.__dict__[key] = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) +value.__dict__.keye = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) +value.__dict__.keye = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) + + +# Don't parenthesize the value because the target's trailing comma forces it to split. +a[ + aaaaaaa, + b, +] = cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc # comment + +# Parenthesize the value, but don't duplicate the comment. +a[aaaaaaa, b] = ( + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc # comment +) + +# Format both as flat, but don't loos the comment. +a[aaaaaaa, b] = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb # comment + +####################################################### +# Test the case where a parenthesized value now fits: +a[ + aaaaaaa, + b +] = ( + cccccccc # comment +) + +# Splits the target but not the value because of the magic trailing comma. +a[ + aaaaaaa, + b, +] = ( + cccccccc # comment +) + +# Splits the second target because of the comment and the first target because of the trailing comma. +a[ + aaaaaaa, + b, +] = ( + # leading comment + b +) = ( + cccccccc # comment +) + + +######## +# Type Alias Statement +type A[str, int, number] = VeryLongTypeNameThatShouldBreakFirstToTheRightBeforeSplitngtin + +type A[VeryLongTypeNameThatShouldBreakFirstToTheRightBeforeSplitngtinthatExceedsTheWidth] = str + +``` + +## Outputs +### Output 1 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Enabled +``` + +```python +####### +# Unsplittable target and value + +# Only parenthesize the value if it makes it fit, otherwise avoid parentheses. +b = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee + +bbbbbbbbbbbbbbbb = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvv +) + +# Avoid parenthesizing the value even if the target exceeds the configured width +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = bbb + + +############ +# Splittable targets + +# Does not double-parenthesize tuples +( + first_item, + second_item, +) = some_looooooooong_module.some_loooooog_function_name( + first_argument, second_argument, third_argument +) + + +# Preserve parentheses around the first target +( + req["ticket"]["steps"]["step"][0]["tasks"]["task"]["fields"]["field"][ + "access_request" + ]["destinations"]["destination"][0]["ip_address"] +) = dst + +# Augmented assignment +req["ticket"]["steps"]["step"][0]["tasks"]["task"]["fields"]["field"][ + "access_request" +] += dst + +# Always parenthesize the value if it avoids splitting the target, regardless of the value's width. +_a: a[aaaa] = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv +) + +##### +# Avoid parenthesizing the value if the expression right before the `=` splits to avoid an unnecessary pair of parentheses + +# The type annotation is guaranteed to split because it is too long. +_a: a[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv +] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv + +# The target is too long +( + aaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvv + +# The target splits because of a magic trailing comma +( + a, + b, +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +# The targets split because of a comment +( + # leading + a +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +( + a + # trailing +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +( + a, # nested + b, +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvvvv + +####### +# Multi targets + +# Black always parenthesizes the right if using multiple targets regardless if the parenthesized value exceeds the +# the configured line width or not +aaaa = bbbbbbbbbbbbbbbb = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee +) + +# Black does parenthesize the target if the target itself exceeds the line width and only parenthesizes +# the values if it makes it fit. +# The second target is too long to ever fit into the configured line width. +aaaa = ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddd +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbvvvvvvvvvvvvvvvvvee + +# Does also apply for other multi target assignments, as soon as a single target exceeds the configured +# width +aaaaaa = a["aaa"] = bbbbb[aa, bbb, cccc] = dddddddddd = eeeeee = ( + fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + +###################### +# Call expressions: +# For unsplittable targets: Parenthesize the call expression if it makes it fit. +# +# For splittable targets: +# Only parenthesize a call expression if the parens of the call don't fit on the same line +# as the target. Don't parenthesize the call expression if the target (or annotation) right before +# splits. + +# Don't parenthesize the function call if the left is unsplittable. +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = a.b.function( + arg1, arg2, arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function( + [1, 2, 3], + arg1, + [1, 2, 3], + arg2, + [1, 2, 3], + arg3, + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd, + eeeeeeeeeeeeee, +) + +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = function() +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = ( + a.b.function(arg1, arg2, arg3) +) +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function() +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function( + [1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3 +) +this_is_a_ridiculously_long_name_and_nobodyddddddddddddddddddddddddddddddd = function( + [1, 2, 3], + arg1, + [1, 2, 3], + arg2, + [1, 2, 3], + arg3, + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd, + eeeeeeeeeeeeee, +) + +####### Fluent call expressions +# Uses the regular `Multiline` layout where the entire `value` gets parenthesized +# if it doesn't fit on the line. +this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use = ( + function().b().c([1, 2, 3], arg1, [1, 2, 3], arg2, [1, 2, 3], arg3) +) + + +####### +# Test comment inlining +value.__dict__[key] = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) +value.__dict__.keye = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) +value.__dict__.keye = ( + "test" # set some Thrift field to non-None in the struct aa bb cc dd ee +) + + +# Don't parenthesize the value because the target's trailing comma forces it to split. +a[ + aaaaaaa, + b, +] = cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc # comment + +# Parenthesize the value, but don't duplicate the comment. +a[aaaaaaa, b] = ( + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc # comment +) + +# Format both as flat, but don't loos the comment. +a[aaaaaaa, b] = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb # comment + +####################################################### +# Test the case where a parenthesized value now fits: +a[aaaaaaa, b] = cccccccc # comment + +# Splits the target but not the value because of the magic trailing comma. +a[ + aaaaaaa, + b, +] = cccccccc # comment + +# Splits the second target because of the comment and the first target because of the trailing comma. +a[ + aaaaaaa, + b, +] = ( + # leading comment + b +) = cccccccc # comment + + +######## +# Type Alias Statement +type A[str, int, number] = ( + VeryLongTypeNameThatShouldBreakFirstToTheRightBeforeSplitngtin +) + +type A[ + VeryLongTypeNameThatShouldBreakFirstToTheRightBeforeSplitngtinthatExceedsTheWidth +] = str +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__ellipsis.pyi.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__ellipsis.pyi.snap index 756fbff9f8e34..89bab19aef384 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__ellipsis.pyi.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__ellipsis.pyi.snap @@ -74,6 +74,10 @@ with True: with True: ... # comment +with True: + ... + # comment + match x: case 1: ... @@ -105,7 +109,8 @@ try: except: ... # comment finally: - ... # comment``` + ... # comment +``` ## Output ```python @@ -163,6 +168,10 @@ with True: with True: ... # comment +with True: + ... + # comment + match x: case 1: ... case 2: diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap index 5b0684becdfa4..4c040409d7c33 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap @@ -416,6 +416,16 @@ def default_arg_comments2(# # ): print(x) + +def function_with_one_argument_and_a_positional_separator( + argument: str, / +) -> ReallyReallyReallyReallyReallyReallyReallyReallyLongName: + pass + +def function_with_one_argument_and_a_keyword_separator( + *, argument: str +) -> ReallyReallyReallyReallyReallyReallyReallyReallyLongName: + pass ``` ## Output @@ -928,7 +938,7 @@ def f( # first def f( # first - a + a, ): # second ... @@ -993,6 +1003,18 @@ def default_arg_comments2( # # ): print(x) + + +def function_with_one_argument_and_a_positional_separator( + argument: str, / +) -> ReallyReallyReallyReallyReallyReallyReallyReallyLongName: + pass + + +def function_with_one_argument_and_a_keyword_separator( + *, argument: str +) -> ReallyReallyReallyReallyReallyReallyReallyReallyLongName: + pass ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__match.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__match.py.snap index 01e0715610701..dad7a3c526f8b 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__match.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__match.py.snap @@ -584,6 +584,11 @@ match n % 3, n % 5: print("Buzz") case _: print(n) + +# Unparenthesized tuples +match x: + case Child(aaaaaaaaa, bbbbbbbbbbbbbbb, cccccc), Doc(aaaaa, bbbbbbbbbb, ddddddddddddd): + pass ``` ## Output @@ -1210,6 +1215,13 @@ match n % 3, n % 5: print("Buzz") case _: print(n) + +# Unparenthesized tuples +match x: + case Child(aaaaaaaaa, bbbbbbbbbbbbbbb, cccccc), Doc( + aaaaa, bbbbbbbbbb, ddddddddddddd + ): + pass ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap index d32669cbbc5b6..d7e7f4074a620 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap @@ -281,7 +281,7 @@ def double( def double( - a: int + a: int, ) -> ( # Hello int ): @@ -289,7 +289,7 @@ def double( def double( - a: int + a: int, ) -> ( # Hello ): return 2 * a @@ -298,7 +298,7 @@ def double( # Breaking over parameters and return types. (Black adds a trailing comma when the # function arguments break here with a single argument; we do not.) def f( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, ) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: ... @@ -310,13 +310,13 @@ def f( def f( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, ) -> a: ... def f( - a + a, ) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: ... @@ -334,13 +334,13 @@ def f[ def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, ) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: ... def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, ) -> a: ... @@ -380,7 +380,7 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> Set[ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ]: @@ -388,7 +388,7 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> Set[ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ]: @@ -396,7 +396,7 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - *args + *args, ) -> Set[ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ]: @@ -431,13 +431,13 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: ... def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: ... @@ -457,7 +457,7 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> X and Y and foooooooooooooooooooooooooooooooooooo(): ... @@ -477,7 +477,7 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> ( X | Y | foooooooooooooooooooooooooooooooooooo() # comment ): @@ -495,7 +495,7 @@ def double() -> ( # Dangling comments on return annotations. def double( - a: int + a: int, ) -> ( int # Hello ): @@ -503,7 +503,7 @@ def double( def double( - a: int + a: int, ) -> ( foo.bar # Hello ): @@ -511,7 +511,7 @@ def double( def double( - a: int + a: int, ) -> ( [int] # Hello ): @@ -519,7 +519,7 @@ def double( def double( - a: int + a: int, ) -> ( int | list[int] # Hello ): @@ -527,7 +527,7 @@ def double( def double( - a: int + a: int, ) -> ( int | list[ @@ -608,7 +608,7 @@ def process_board_action( @@ -95,50 +89,44 @@ # function arguments break here with a single argument; we do not.) def f( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, -) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... +) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: ... @@ -622,14 +622,14 @@ def process_board_action( def f( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, -) -> a: - ... +) -> a: ... def f( - a + a, -) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... +) -> ( @@ -652,14 +652,14 @@ def process_board_action( def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, -) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... +) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: ... def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, -) -> a: - ... +) -> a: ... @@ -703,7 +703,7 @@ def process_board_action( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> Set[ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -]: @@ -712,7 +712,7 @@ def process_board_action( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> Set[ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -]: @@ -721,7 +721,7 @@ def process_board_action( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - *args + *args, ) -> Set[ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -]: @@ -761,14 +761,14 @@ def process_board_action( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, -) -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: - ... +) -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: ... def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, -) -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: - ... +) -> ( @@ -786,7 +786,7 @@ def process_board_action( -def xxxxxxxxxxxxxxxxxxxxxxxxxxxx(x) -> X + Y + foooooooooooooooooooooooooooooooooooo(): - ... +def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( -+ x ++ x, +) -> X + Y + foooooooooooooooooooooooooooooooooooo(): ... @@ -798,7 +798,7 @@ def process_board_action( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, -) -> X and Y and foooooooooooooooooooooooooooooooooooo(): - ... +) -> X and Y and foooooooooooooooooooooooooooooooooooo(): ... @@ -814,7 +814,7 @@ def process_board_action( -def xxxxxxxxxxxxxxxxxxxxxxxxxxxx(x) -> X | Y | foooooooooooooooooooooooooooooooooooo(): - ... +def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( -+ x ++ x, +) -> X | Y | foooooooooooooooooooooooooooooooooooo(): ... @@ -826,7 +826,7 @@ def process_board_action( def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( - x + x, ) -> ( X | Y | foooooooooooooooooooooooooooooooooooo() # comment -): diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__type_alias.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__type_alias.py.snap index ccc44b8db950a..6320591b80c05 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__type_alias.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__type_alias.py.snap @@ -22,10 +22,12 @@ type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[Aaaaaaaaaaaaaaaaaaaaaaaaaaaa] = int type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[Aaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbb] = int type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = Tttttttttttttttttttttttttttttttttttttttttttttttttttttttt +type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = Tttttttttttttttttttttttttttttttttttttttttttttttttttttttt # with comment # long value type X = Ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt type X = Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | Ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +type XXXXXXXXXXXXX = Tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt # with comment # soft keyword as alias name type type = int @@ -127,6 +129,9 @@ type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Bbbbbbbbbbbbb, ] = int type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = Tttttttttttttttttttttttttttttttttttttttttttttttttttttttt +type Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = ( + Tttttttttttttttttttttttttttttttttttttttttttttttttttttttt # with comment +) # long value type X = Ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt @@ -135,6 +140,9 @@ type X = ( | Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | Ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ) +type XXXXXXXXXXXXX = ( + Tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt # with comment +) # soft keyword as alias name type type = int diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap index 7b2280c6caf31..62018dfe4e1d4 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap @@ -309,6 +309,10 @@ if True: if True: with anyio.CancelScope(shield=True) if get_running_loop() else contextlib.nullcontext(): pass + + +with Child(aaaaaaaaa, bbbbbbbbbbbbbbb, cccccc), Document(aaaaa, bbbbbbbbbb, ddddddddddddd): + pass ``` ## Output @@ -640,6 +644,12 @@ if True: shield=True ) if get_running_loop() else contextlib.nullcontext(): pass + + +with Child(aaaaaaaaa, bbbbbbbbbbbbbbb, cccccc), Document( + aaaaa, bbbbbbbbbb, ddddddddddddd +): + pass ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap index 2ff5d8afde9b6..ea85babc1bab7 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap @@ -17,12 +17,15 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/tab_width. ## Outputs ### Output 1 ``` -indent-style = space -line-width = 88 -indent-width = 2 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 2 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -39,12 +42,15 @@ preview = Disabled ### Output 2 ``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python @@ -64,12 +70,15 @@ preview = Disabled ### Output 3 ``` -indent-style = space -line-width = 88 -indent-width = 8 -quote-style = Double -magic-trailing-comma = Respect -preview = Disabled +indent-style = space +line-width = 88 +indent-width = 8 +quote-style = Double +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +docstring-code-line-width = "dynamic" +preview = Disabled ``` ```python diff --git a/crates/ruff_python_literal/src/escape.rs b/crates/ruff_python_literal/src/escape.rs index 01de325f102d7..1894bbff952af 100644 --- a/crates/ruff_python_literal/src/escape.rs +++ b/crates/ruff_python_literal/src/escape.rs @@ -415,12 +415,10 @@ impl<'a> Escape for AsciiEscape<'a> { fn layout(&self) -> &EscapeLayout { &self.layout } - #[allow(unsafe_code)] fn write_source(&self, formatter: &mut impl std::fmt::Write) -> std::fmt::Result { - formatter.write_str(unsafe { - // SAFETY: this function must be called only when source is printable ascii characters - std::str::from_utf8_unchecked(self.source) - }) + // OK because function must be called only when source is printable ascii characters. + let string = std::str::from_utf8(self.source).expect("ASCII bytes"); + formatter.write_str(string) } #[cold] diff --git a/crates/ruff_python_parser/src/invalid.rs b/crates/ruff_python_parser/src/invalid.rs index 8424567113f73..91f81bd5eac48 100644 --- a/crates/ruff_python_parser/src/invalid.rs +++ b/crates/ruff_python_parser/src/invalid.rs @@ -59,7 +59,6 @@ pub(crate) fn assignment_target(target: &Expr) -> Result<(), LexicalError> { YieldFrom(ref e) => Err(err(e.range.start())), Compare(ref e) => Err(err(e.range.start())), Call(ref e) => Err(err(e.range.start())), - FormattedValue(ref e) => Err(err(e.range.start())), // FString is recursive, but all its forms are invalid as an // assignment target, so we can reject it without exploring it. FString(ref e) => Err(err(e.range.start())), diff --git a/crates/ruff_python_parser/src/lexer.rs b/crates/ruff_python_parser/src/lexer.rs index 2ce3d17c8e449..3831bc28d0315 100644 --- a/crates/ruff_python_parser/src/lexer.rs +++ b/crates/ruff_python_parser/src/lexer.rs @@ -2160,6 +2160,14 @@ f"{(lambda x:{x})}" assert_debug_snapshot!(lex_source(source)); } + #[test] + fn test_match_softkeyword_in_notebook() { + let source = r"match foo: + case bar: + pass"; + assert_debug_snapshot!(lex_jupyter_source(source)); + } + fn lex_fstring_error(source: &str) -> FStringErrorType { match lex(source, Mode::Module).find_map(std::result::Result::err) { Some(err) => match err.error { diff --git a/crates/ruff_python_parser/src/lexer/cursor.rs b/crates/ruff_python_parser/src/lexer/cursor.rs index 91c7d30c53b05..26f3bb8a5b402 100644 --- a/crates/ruff_python_parser/src/lexer/cursor.rs +++ b/crates/ruff_python_parser/src/lexer/cursor.rs @@ -120,6 +120,7 @@ impl<'a> Cursor<'a> { } /// Eats symbols while predicate returns true or until the end of file is reached. + #[inline] pub(super) fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) { // It was tried making optimized version of this for eg. line comments, but // LLVM can inline all of this and compile it down to fast iteration over bytes. diff --git a/crates/ruff_python_parser/src/parser.rs b/crates/ruff_python_parser/src/parser.rs index 82b5a26b8f89b..26603ca3dda4e 100644 --- a/crates/ruff_python_parser/src/parser.rs +++ b/crates/ruff_python_parser/src/parser.rs @@ -16,7 +16,7 @@ use std::{fmt, iter}; use itertools::Itertools; pub(super) use lalrpop_util::ParseError as LalrpopError; -use ruff_text_size::{TextRange, TextSize}; +use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::lexer::{lex, lex_starts_at, Spanned}; use crate::{ @@ -25,8 +25,14 @@ use crate::{ token::Tok, Mode, }; -use ruff_python_ast as ast; -use ruff_python_ast::{Mod, ModModule, Suite}; +use ruff_python_ast::{ + Expr, ExprAttribute, ExprAwait, ExprBinOp, ExprBoolOp, ExprBooleanLiteral, ExprBytesLiteral, + ExprCall, ExprCompare, ExprDict, ExprDictComp, ExprEllipsisLiteral, ExprFString, + ExprGeneratorExp, ExprIfExp, ExprIpyEscapeCommand, ExprLambda, ExprList, ExprListComp, + ExprName, ExprNamedExpr, ExprNoneLiteral, ExprNumberLiteral, ExprSet, ExprSetComp, ExprSlice, + ExprStarred, ExprStringLiteral, ExprSubscript, ExprTuple, ExprUnaryOp, ExprYield, + ExprYieldFrom, Mod, ModModule, Suite, +}; /// Parse a full Python program usually consisting of multiple lines. /// @@ -76,7 +82,7 @@ pub fn parse_suite(source: &str, source_path: &str) -> Result /// assert!(expr.is_ok()); /// /// ``` -pub fn parse_expression(source: &str, source_path: &str) -> Result { +pub fn parse_expression(source: &str, source_path: &str) -> Result { let lexer = lex(source, Mode::Expression); match parse_tokens(lexer, source, Mode::Expression, source_path)? { Mod::Expression(expression) => Ok(*expression.body), @@ -105,7 +111,7 @@ pub fn parse_expression_starts_at( source: &str, source_path: &str, offset: TextSize, -) -> Result { +) -> Result { let lexer = lex_starts_at(source, Mode::Module, offset); match parse_tokens(lexer, source, Mode::Expression, source_path)? { Mod::Expression(expression) => Ok(*expression.body), @@ -418,6 +424,209 @@ impl ParseErrorType { } } +/// An expression that may be parenthesized. +#[derive(Clone, Debug)] +pub(super) struct ParenthesizedExpr { + /// The range of the expression, including any parentheses. + pub(super) range: TextRange, + /// The underlying expression. + pub(super) expr: Expr, +} + +impl ParenthesizedExpr { + /// Returns `true` if the expression is parenthesized. + pub(super) fn is_parenthesized(&self) -> bool { + self.range.start() != self.expr.range().start() + } +} + +impl Ranged for ParenthesizedExpr { + fn range(&self) -> TextRange { + self.range + } +} +impl From for ParenthesizedExpr { + fn from(expr: Expr) -> Self { + ParenthesizedExpr { + range: expr.range(), + expr, + } + } +} +impl From for Expr { + fn from(parenthesized_expr: ParenthesizedExpr) -> Self { + parenthesized_expr.expr + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprIpyEscapeCommand) -> Self { + Expr::IpyEscapeCommand(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprBoolOp) -> Self { + Expr::BoolOp(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprNamedExpr) -> Self { + Expr::NamedExpr(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprBinOp) -> Self { + Expr::BinOp(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprUnaryOp) -> Self { + Expr::UnaryOp(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprLambda) -> Self { + Expr::Lambda(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprIfExp) -> Self { + Expr::IfExp(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprDict) -> Self { + Expr::Dict(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprSet) -> Self { + Expr::Set(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprListComp) -> Self { + Expr::ListComp(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprSetComp) -> Self { + Expr::SetComp(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprDictComp) -> Self { + Expr::DictComp(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprGeneratorExp) -> Self { + Expr::GeneratorExp(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprAwait) -> Self { + Expr::Await(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprYield) -> Self { + Expr::Yield(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprYieldFrom) -> Self { + Expr::YieldFrom(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprCompare) -> Self { + Expr::Compare(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprCall) -> Self { + Expr::Call(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprFString) -> Self { + Expr::FString(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprStringLiteral) -> Self { + Expr::StringLiteral(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprBytesLiteral) -> Self { + Expr::BytesLiteral(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprNumberLiteral) -> Self { + Expr::NumberLiteral(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprBooleanLiteral) -> Self { + Expr::BooleanLiteral(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprNoneLiteral) -> Self { + Expr::NoneLiteral(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprEllipsisLiteral) -> Self { + Expr::EllipsisLiteral(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprAttribute) -> Self { + Expr::Attribute(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprSubscript) -> Self { + Expr::Subscript(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprStarred) -> Self { + Expr::Starred(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprName) -> Self { + Expr::Name(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprList) -> Self { + Expr::List(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprTuple) -> Self { + Expr::Tuple(payload).into() + } +} +impl From for ParenthesizedExpr { + fn from(payload: ExprSlice) -> Self { + Expr::Slice(payload).into() + } +} + +#[cfg(target_pointer_width = "64")] +mod size_assertions { + use crate::parser::ParenthesizedExpr; + use static_assertions::assert_eq_size; + + assert_eq_size!(ParenthesizedExpr, [u8; 88]); +} + #[cfg(test)] mod tests { use insta::assert_debug_snapshot; @@ -822,6 +1031,10 @@ type X \ [T] = T type X[T] \ = T + +# simple statements +type X = int; type X = str; type X = type +class X: type X = int "#; insta::assert_debug_snapshot!(parse_suite(source, "").unwrap()); } @@ -859,10 +1072,17 @@ type ( type = 1 type = x = 1 x = type = 1 +lambda x: type "; insta::assert_debug_snapshot!(parse_suite(source, "").unwrap()); } + #[test] + fn test_invalid_type() { + assert!(parse_suite("a: type X = int", "").is_err()); + assert!(parse_suite("lambda: type X = int", "").is_err()); + } + #[test] fn numeric_literals() { let source = r"x = 123456789 diff --git a/crates/ruff_python_parser/src/python.lalrpop b/crates/ruff_python_parser/src/python.lalrpop index 9c73f648bfd61..aa87fcd72d4f0 100644 --- a/crates/ruff_python_parser/src/python.lalrpop +++ b/crates/ruff_python_parser/src/python.lalrpop @@ -11,7 +11,7 @@ use crate::{ lexer::{LexicalError, LexicalErrorType}, function::{ArgumentList, parse_arguments, validate_pos_params, validate_arguments}, context::set_context, - string::{StringType, concatenate_strings, parse_fstring_middle, parse_string_literal}, + string::{StringType, concatenated_strings, parse_fstring_literal_element, parse_string_literal}, token::{self, StringKind}, invalid, }; @@ -156,33 +156,33 @@ ExpressionStatement: ast::Stmt = { }, }; -AssignSuffix: ast::ParenthesizedExpr = { +AssignSuffix: crate::parser::ParenthesizedExpr = { "=" => e, "=" => e }; -TestListOrYieldExpr: ast::ParenthesizedExpr = { +TestListOrYieldExpr: crate::parser::ParenthesizedExpr = { TestList, YieldExpr } #[inline] -TestOrStarExprList: ast::ParenthesizedExpr = { +TestOrStarExprList: crate::parser::ParenthesizedExpr = { // as far as I can tell, these were the same TestList }; -TestOrStarExpr: ast::ParenthesizedExpr = { +TestOrStarExpr: crate::parser::ParenthesizedExpr = { Test<"all">, StarExpr, }; -NamedOrStarExpr: ast::ParenthesizedExpr = { +NamedOrStarExpr: crate::parser::ParenthesizedExpr = { NamedExpression, StarExpr, }; -TestOrStarNamedExpr: ast::ParenthesizedExpr = { +TestOrStarNamedExpr: crate::parser::ParenthesizedExpr = { NamedExpressionTest, StarExpr, }; @@ -345,7 +345,7 @@ IpyEscapeCommandStatement: ast::Stmt = { } } -IpyEscapeCommandExpr: ast::ParenthesizedExpr = { +IpyEscapeCommandExpr: crate::parser::ParenthesizedExpr = { =>? { if mode == Mode::Ipython { // This should never occur as the lexer won't allow it. @@ -399,7 +399,7 @@ IpyHelpEndEscapeCommandStatement: ast::Stmt = { _ => { return Err(LexicalError { error: LexicalErrorType::OtherError("only Name, Subscript and Attribute expressions are allowed in help end escape command".to_string()), - location: expr.range().start(), + location: expr.start(), }); } } @@ -491,7 +491,7 @@ MatchStatement: ast::Stmt = { } ) }, - "match" > ","? ":" "\n" Indent Dedent => { + "match" > ","? ":" "\n" Indent Dedent => { let end_location = cases .last() .unwrap() @@ -542,7 +542,7 @@ Patterns: ast::Pattern = { range: (location..end_location).into() }, ), - > ","? => { + > ","? => { ast::Pattern::MatchSequence( ast::PatternMatchSequence { patterns, @@ -579,7 +579,7 @@ AsPattern: ast::Pattern = { OrPattern: ast::Pattern = { => pattern, - > => { + > => { ast::Pattern::MatchOr( ast::PatternMatchOr { patterns, range: (location..end_location).into() } ) @@ -630,13 +630,13 @@ StarPattern: ast::Pattern = { }.into(), } -NumberAtom: ast::ParenthesizedExpr = { +NumberAtom: crate::parser::ParenthesizedExpr = { => ast::Expr::NumberLiteral( ast::ExprNumberLiteral { value, range: (location..end_location).into() } ).into(), } -NumberExpr: ast::ParenthesizedExpr = { +NumberExpr: crate::parser::ParenthesizedExpr = { NumberAtom, "-" => ast::Expr::UnaryOp( ast::ExprUnaryOp { @@ -647,7 +647,7 @@ NumberExpr: ast::ParenthesizedExpr = { ).into(), } -AddOpExpr: ast::ParenthesizedExpr = { +AddOpExpr: crate::parser::ParenthesizedExpr = { => ast::ExprBinOp { left: Box::new(left.into()), op, @@ -677,8 +677,12 @@ LiteralPattern: ast::Pattern = { value: Box::new(value.into()), range: (location..end_location).into() }.into(), - =>? Ok(ast::PatternMatchValue { - value: Box::new(concatenate_strings(strings, (location..end_location).into())?), + => ast::PatternMatchValue { + value: Box::new(string.into()), + range: (location..end_location).into() + }.into(), + > =>? Ok(ast::PatternMatchValue { + value: Box::new(concatenated_strings(strings, (location..end_location).into())?), range: (location..end_location).into() }.into()), } @@ -721,6 +725,7 @@ ValuePattern: ast::Pattern = { MappingKey: ast::Expr = { MatchNameOrAttr, + String, => e.into(), => e.into(), "None" => ast::ExprNoneLiteral { @@ -734,7 +739,6 @@ MappingKey: ast::Expr = { value: false, range: (location..end_location).into() }.into(), - =>? Ok(concatenate_strings(strings, (location..end_location).into())?), } MatchMappingEntry: (ast::Expr, ast::Pattern) = { @@ -1022,7 +1026,7 @@ WithItems: Vec = { // ``` // In this case, the `(` and `)` are part of the `with` statement. // The same applies to `yield` and `yield from`. - let item = if matches!(item.context_expr, ast::Expr::NamedExpr(_) | ast::Expr::Yield(_) | ast::Expr::YieldFrom(_)) { + let item = if item.optional_vars.is_none() && matches!(item.context_expr, ast::Expr::NamedExpr(_) | ast::Expr::Yield(_) | ast::Expr::YieldFrom(_)) { ast::WithItem { range: item.range().add_start(TextSize::new(1)).sub_end(TextSize::new(1)), context_expr: item.context_expr, @@ -1312,7 +1316,7 @@ Decorator: ast::Decorator = { }, }; -YieldExpr: ast::ParenthesizedExpr = { +YieldExpr: crate::parser::ParenthesizedExpr = { "yield" => ast::ExprYield { value: value.map(ast::Expr::from).map(Box::new), range: (location..end_location).into(), @@ -1323,7 +1327,7 @@ YieldExpr: ast::ParenthesizedExpr = { }.into(), }; -Test: ast::ParenthesizedExpr = { +Test: crate::parser::ParenthesizedExpr = { > "if" > "else" > => ast::ExprIfExp { test: Box::new(test.into()), body: Box::new(body.into()), @@ -1334,12 +1338,12 @@ Test: ast::ParenthesizedExpr = { LambdaDef, }; -NamedExpressionTest: ast::ParenthesizedExpr = { +NamedExpressionTest: crate::parser::ParenthesizedExpr = { NamedExpression, Test<"all">, } -NamedExpressionName: ast::ParenthesizedExpr = { +NamedExpressionName: crate::parser::ParenthesizedExpr = { => ast::ExprName { id: id.into(), ctx: ast::ExprContext::Store, @@ -1347,7 +1351,7 @@ NamedExpressionName: ast::ParenthesizedExpr = { }.into(), } -NamedExpression: ast::ParenthesizedExpr = { +NamedExpression: crate::parser::ParenthesizedExpr = { ":=" > => { ast::ExprNamedExpr { target: Box::new(target.into()), @@ -1357,7 +1361,7 @@ NamedExpression: ast::ParenthesizedExpr = { }, }; -LambdaDef: ast::ParenthesizedExpr = { +LambdaDef: crate::parser::ParenthesizedExpr = { "lambda" ?> ":" > =>? { if fstring_middle.is_some() { return Err(LexicalError { @@ -1375,7 +1379,7 @@ LambdaDef: ast::ParenthesizedExpr = { } } -OrTest: ast::ParenthesizedExpr = { +OrTest: crate::parser::ParenthesizedExpr = { > "or")+> > => { let values = values.into_iter().chain(std::iter::once(last)).map(ast::Expr::from).collect(); ast::ExprBoolOp { op: ast::BoolOp::Or, values, range: (location..end_location).into() }.into() @@ -1383,7 +1387,7 @@ OrTest: ast::ParenthesizedExpr = { AndTest, }; -AndTest: ast::ParenthesizedExpr = { +AndTest: crate::parser::ParenthesizedExpr = { > "and")+> > => { let values = values.into_iter().chain(std::iter::once(last)).map(ast::Expr::from).collect(); ast::ExprBoolOp { op: ast::BoolOp::And, values, range: (location..end_location).into() }.into() @@ -1391,7 +1395,7 @@ AndTest: ast::ParenthesizedExpr = { NotTest, }; -NotTest: ast::ParenthesizedExpr = { +NotTest: crate::parser::ParenthesizedExpr = { "not" > => ast::ExprUnaryOp { operand: Box::new(operand.into()), op: ast::UnaryOp::Not, @@ -1400,7 +1404,7 @@ NotTest: ast::ParenthesizedExpr = { Comparison, }; -Comparison: ast::ParenthesizedExpr = { +Comparison: crate::parser::ParenthesizedExpr = { > )+> => { let (ops, comparators) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip(); ast::ExprCompare { left: Box::new(left.into()), ops, comparators, range: (location..end_location).into() }.into() @@ -1421,7 +1425,7 @@ CompOp: ast::CmpOp = { "is" "not" => ast::CmpOp::IsNot, }; -Expression: ast::ParenthesizedExpr = { +Expression: crate::parser::ParenthesizedExpr = { > "|" > => ast::ExprBinOp { left: Box::new(left.into()), op: ast::Operator::BitOr, @@ -1431,7 +1435,7 @@ Expression: ast::ParenthesizedExpr = { XorExpression, }; -XorExpression: ast::ParenthesizedExpr = { +XorExpression: crate::parser::ParenthesizedExpr = { > "^" > => ast::ExprBinOp { left: Box::new(left.into()), op: ast::Operator::BitXor, @@ -1441,7 +1445,7 @@ XorExpression: ast::ParenthesizedExpr = { AndExpression, }; -AndExpression: ast::ParenthesizedExpr = { +AndExpression: crate::parser::ParenthesizedExpr = { > "&" > => ast::ExprBinOp { left: Box::new(left.into()), op: ast::Operator::BitAnd, @@ -1451,7 +1455,7 @@ AndExpression: ast::ParenthesizedExpr = { ShiftExpression, }; -ShiftExpression: ast::ParenthesizedExpr = { +ShiftExpression: crate::parser::ParenthesizedExpr = { > > => ast::ExprBinOp { left: Box::new(left.into()), op, @@ -1466,7 +1470,7 @@ ShiftOp: ast::Operator = { ">>" => ast::Operator::RShift, }; -ArithmeticExpression: ast::ParenthesizedExpr = { +ArithmeticExpression: crate::parser::ParenthesizedExpr = { > > => ast::ExprBinOp { left: Box::new(left.into()), op, @@ -1481,7 +1485,7 @@ AddOp: ast::Operator = { "-" => ast::Operator::Sub, }; -Term: ast::ParenthesizedExpr = { +Term: crate::parser::ParenthesizedExpr = { > > => ast::ExprBinOp { left: Box::new(left.into()), op, @@ -1499,7 +1503,7 @@ MulOp: ast::Operator = { "@" => ast::Operator::MatMult, }; -Factor: ast::ParenthesizedExpr = { +Factor: crate::parser::ParenthesizedExpr = { > => ast::ExprUnaryOp { operand: Box::new(operand.into()), op, @@ -1514,7 +1518,7 @@ UnaryOp: ast::UnaryOp = { "~" => ast::UnaryOp::Invert, }; -Power: ast::ParenthesizedExpr = { +Power: crate::parser::ParenthesizedExpr = { > "**" > => ast::ExprBinOp { left: Box::new(left.into()), op: ast::Operator::Pow, @@ -1524,14 +1528,14 @@ Power: ast::ParenthesizedExpr = { AtomExpr, }; -AtomExpr: ast::ParenthesizedExpr = { +AtomExpr: crate::parser::ParenthesizedExpr = { "await" > => { ast::ExprAwait { value: Box::new(value.into()), range: (location..end_location).into() }.into() }, AtomExpr2, } -AtomExpr2: ast::ParenthesizedExpr = { +AtomExpr2: crate::parser::ParenthesizedExpr = { Atom, > => ast::ExprCall { func: Box::new(func.into()), @@ -1552,7 +1556,7 @@ AtomExpr2: ast::ParenthesizedExpr = { }.into(), }; -SubscriptList: ast::ParenthesizedExpr = { +SubscriptList: crate::parser::ParenthesizedExpr = { Subscript, "," => { ast::ExprTuple { @@ -1561,7 +1565,7 @@ SubscriptList: ast::ParenthesizedExpr = { range: (location..end_location).into(), }.into() }, - > ","? => { + > ","? => { let elts = elts.into_iter().map(ast::Expr::from).collect(); ast::ExprTuple { elts, @@ -1571,7 +1575,7 @@ SubscriptList: ast::ParenthesizedExpr = { } }; -Subscript: ast::ParenthesizedExpr = { +Subscript: crate::parser::ParenthesizedExpr = { TestOrStarNamedExpr, ?> ":" ?> => { let lower = lower.map(ast::Expr::from).map(Box::new); @@ -1583,41 +1587,47 @@ Subscript: ast::ParenthesizedExpr = { } }; -SliceOp: Option = { +SliceOp: Option = { ":" ?> => e, } +String: ast::Expr = { + => string.into(), + > =>? { + Ok(concatenated_strings(strings, (location..end_location).into())?) + } +}; + StringLiteralOrFString: StringType = { StringLiteral, FStringExpr, }; StringLiteral: StringType = { - =>? { + =>? { let (source, kind, triple_quoted) = string; - Ok(parse_string_literal(&source, kind, triple_quoted, start_location)?) + Ok(parse_string_literal(&source, kind, triple_quoted, (location..end_location).into())?) } }; FStringExpr: StringType = { - FStringStart FStringEnd => { - StringType::FString(ast::ExprFString { - values, - implicit_concatenated: false, + FStringStart FStringEnd => { + StringType::FString(ast::FString { + elements, range: (location..end_location).into() }) } }; -FStringMiddlePattern: ast::Expr = { +FStringMiddlePattern: ast::FStringElement = { FStringReplacementField, - =>? { + =>? { let (source, is_raw) = fstring_middle; - Ok(parse_fstring_middle(&source, is_raw, start_location)?) + Ok(parse_fstring_literal_element(&source, is_raw, (location..end_location).into())?) } }; -FStringReplacementField: ast::Expr = { +FStringReplacementField: ast::FStringElement = { "{" "}" =>? { if value.expr.is_lambda_expr() && !value.is_parenthesized() { return Err(LexicalError { @@ -1632,40 +1642,36 @@ FStringReplacementField: ast::Expr = { } else { format_spec.as_ref().map_or_else( || end_location - "}".text_len(), - |spec| spec.range().start() - ":".text_len(), + |spec| spec.start() - ":".text_len(), ) }; ast::DebugText { - leading: source_code[TextRange::new(start_offset, value.range().start())].to_string(), - trailing: source_code[TextRange::new(value.range().end(), end_offset)].to_string(), + leading: source_code[TextRange::new(start_offset, value.start())].to_string(), + trailing: source_code[TextRange::new(value.end(), end_offset)].to_string(), } }); Ok( - ast::ExprFormattedValue { - value: Box::new(value.into()), + ast::FStringElement::Expression(ast::FStringExpressionElement { + expression: Box::new(value.into()), debug_text, conversion: conversion.map_or(ast::ConversionFlag::None, |(_, conversion_flag)| { conversion_flag }), format_spec: format_spec.map(Box::new), range: (location..end_location).into(), - } - .into() + }) ) } }; -FStringFormatSpecSuffix: ast::Expr = { +FStringFormatSpecSuffix: ast::FStringFormatSpec = { ":" => format_spec }; -FStringFormatSpec: ast::Expr = { - => { - ast::ExprFString { - values, - implicit_concatenated: false, - range: (location..end_location).into() - }.into() +FStringFormatSpec: ast::FStringFormatSpec = { + => ast::FStringFormatSpec { + elements, + range: (location..end_location).into(), }, }; @@ -1684,8 +1690,8 @@ FStringConversion: (TextSize, ast::ConversionFlag) = { } }; -Atom: ast::ParenthesizedExpr = { - =>? Ok(concatenate_strings(strings, (location..end_location).into())?.into()), +Atom: crate::parser::ParenthesizedExpr = { + => expr.into(), => ast::ExprNumberLiteral { value, range: (location..end_location).into(), @@ -1704,7 +1710,7 @@ Atom: ast::ParenthesizedExpr = { }, "(" >> ")" if Goal != "no-withitems" => { if elts.len() == 1 && trailing_comma.is_none() { - ast::ParenthesizedExpr { + crate::parser::ParenthesizedExpr { expr: elts.into_iter().next().unwrap().into(), range: (location..end_location).into(), } @@ -1721,7 +1727,7 @@ Atom: ast::ParenthesizedExpr = { location: mid.start(), })?; } - Ok(ast::ParenthesizedExpr { + Ok(crate::parser::ParenthesizedExpr { expr: mid.into(), range: (location..end_location).into(), }) @@ -1735,7 +1741,7 @@ Atom: ast::ParenthesizedExpr = { ctx: ast::ExprContext::Load, range: (location..end_location).into(), }.into(), - "(" ")" => ast::ParenthesizedExpr { + "(" ")" => crate::parser::ParenthesizedExpr { expr: e.into(), range: (location..end_location).into(), }, @@ -1784,37 +1790,37 @@ Atom: ast::ParenthesizedExpr = { "..." => ast::ExprEllipsisLiteral { range: (location..end_location).into() }.into(), }; -ListLiteralValues: Vec = { +ListLiteralValues: Vec = { > ","? => e, }; -DictLiteralValues: Vec<(Option>, ast::ParenthesizedExpr)> = { +DictLiteralValues: Vec<(Option>, crate::parser::ParenthesizedExpr)> = { > ","? => elements, }; -DictEntry: (ast::ParenthesizedExpr, ast::ParenthesizedExpr) = { +DictEntry: (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr) = { > ":" > => (e1, e2), }; -DictElement: (Option>, ast::ParenthesizedExpr) = { +DictElement: (Option>, crate::parser::ParenthesizedExpr) = { => (Some(Box::new(e.0)), e.1), "**" > => (None, e), }; -SetLiteralValues: Vec = { +SetLiteralValues: Vec = { > ","? => e1 }; -ExpressionOrStarExpression: ast::ParenthesizedExpr = { +ExpressionOrStarExpression: crate::parser::ParenthesizedExpr = { Expression<"all">, StarExpr }; -ExpressionList: ast::ParenthesizedExpr = { +ExpressionList: crate::parser::ParenthesizedExpr = { GenericList }; -ExpressionList2: Vec = { +ExpressionList2: Vec = { > ","? => elements, }; @@ -1823,14 +1829,14 @@ ExpressionList2: Vec = { // - a single expression // - a single expression followed by a trailing comma #[inline] -TestList: ast::ParenthesizedExpr = { +TestList: crate::parser::ParenthesizedExpr = { GenericList }; -GenericList: ast::ParenthesizedExpr = { +GenericList: crate::parser::ParenthesizedExpr = { > => { if elts.len() == 1 && trailing_comma.is_none() { - ast::ParenthesizedExpr { + crate::parser::ParenthesizedExpr { expr: elts.into_iter().next().unwrap().into(), range: (location..end_location).into(), } @@ -1842,7 +1848,7 @@ GenericList: ast::ParenthesizedExpr = { } // Test -StarExpr: ast::ParenthesizedExpr = { +StarExpr: crate::parser::ParenthesizedExpr = { "*" > => ast::ExprStarred { value: Box::new(value.into()), ctx: ast::ExprContext::Load, @@ -1867,8 +1873,8 @@ SingleForComprehension: ast::Comprehension = { } }; -ExpressionNoCond: ast::ParenthesizedExpr = OrTest<"all">; -ComprehensionIf: ast::ParenthesizedExpr = "if" => c; +ExpressionNoCond: crate::parser::ParenthesizedExpr = OrTest<"all">; +ComprehensionIf: crate::parser::ParenthesizedExpr = "if" => c; Arguments: ast::Arguments = { "(" > ")" =>? { @@ -1926,9 +1932,18 @@ OneOrMore: Vec = { }; /// Two or more items that are separated by `Sep` -TwoOrMore: Vec = { +TwoOrMoreSep: Vec = { Sep => vec![e1, e2], - > Sep => { + > Sep => { + v.push(e); + v + } +}; + +/// Two or more items that are contiguous. +TwoOrMore: Vec = { + => vec![e1, e2], + > => { v.push(e); v } diff --git a/crates/ruff_python_parser/src/python.rs b/crates/ruff_python_parser/src/python.rs index bfbd1475dd947..5771d7099f737 100644 --- a/crates/ruff_python_parser/src/python.rs +++ b/crates/ruff_python_parser/src/python.rs @@ -1,5 +1,5 @@ // auto-generated: "lalrpop 0.20.0" -// sha3: b8ac4a859b69d580e50733d39c96a3fe018f568e71e532ebb3153a19902e64e5 +// sha3: 031689e389556292d9dbd8a1b1ff8ca29bac76d83f1b345630481d620b89e1c2 use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_python_ast::{self as ast, Int, IpyEscapeKind}; use crate::{ @@ -8,7 +8,7 @@ use crate::{ lexer::{LexicalError, LexicalErrorType}, function::{ArgumentList, parse_arguments, validate_pos_params, validate_arguments}, context::set_context, - string::{StringType, concatenate_strings, parse_fstring_middle, parse_string_literal}, + string::{StringType, concatenated_strings, parse_fstring_literal_element, parse_string_literal}, token::{self, StringKind}, invalid, }; @@ -32,7 +32,7 @@ mod __parse__Top { lexer::{LexicalError, LexicalErrorType}, function::{ArgumentList, parse_arguments, validate_pos_params, validate_arguments}, context::set_context, - string::{StringType, concatenate_strings, parse_fstring_middle, parse_string_literal}, + string::{StringType, concatenated_strings, parse_fstring_literal_element, parse_string_literal}, token::{self, StringKind}, invalid, }; @@ -62,9 +62,9 @@ mod __parse__Top { Variant12(alloc::vec::Vec), Variant13((Option>, Vec, Option>)), Variant14(core::option::Option<(Option>, Vec, Option>)>), - Variant15(ast::ParenthesizedExpr), - Variant16(core::option::Option), - Variant17(alloc::vec::Vec), + Variant15(crate::parser::ParenthesizedExpr), + Variant16(core::option::Option), + Variant17(alloc::vec::Vec), Variant18(ast::WithItem), Variant19(alloc::vec::Vec), Variant20((token::Tok, ast::Identifier)), @@ -74,23 +74,23 @@ mod __parse__Top { Variant24(core::option::Option), Variant25(ast::Suite), Variant26(core::option::Option), - Variant27((TextSize, ast::ParenthesizedExpr, ast::Suite)), - Variant28(alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>), + Variant27((TextSize, crate::parser::ParenthesizedExpr, ast::Suite)), + Variant28(alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>), Variant29((TextSize, ast::Suite)), Variant30(core::option::Option<(TextSize, ast::Suite)>), Variant31((Option<(TextSize, TextSize, Option)>, ast::Expr)), Variant32(alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), - Variant33(Vec), - Variant34(core::option::Option>), + Variant33(Vec), + Variant34(core::option::Option>), Variant35(ast::Pattern), Variant36(alloc::vec::Vec), Variant37(ast::Stmt), Variant38(alloc::vec::Vec), - Variant39((ast::ParenthesizedExpr, ast::Identifier)), + Variant39((crate::parser::ParenthesizedExpr, ast::Identifier)), Variant40(Vec), Variant41(core::option::Option>), - Variant42((ast::CmpOp, ast::ParenthesizedExpr)), - Variant43(alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>), + Variant42((ast::CmpOp, crate::parser::ParenthesizedExpr)), + Variant43(alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>), Variant44(ast::Expr), Variant45(core::option::Option), Variant46(ast::Parameters), @@ -106,10 +106,10 @@ mod __parse__Top { Variant56(ast::CmpOp), Variant57(ast::Decorator), Variant58(alloc::vec::Vec), - Variant59((Option>, ast::ParenthesizedExpr)), - Variant60((ast::ParenthesizedExpr, ast::ParenthesizedExpr)), - Variant61(Vec<(Option>, ast::ParenthesizedExpr)>), - Variant62(core::option::Option>, ast::ParenthesizedExpr)>>), + Variant59((Option>, crate::parser::ParenthesizedExpr)), + Variant60((crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr)), + Variant61(Vec<(Option>, crate::parser::ParenthesizedExpr)>), + Variant62(core::option::Option>, crate::parser::ParenthesizedExpr)>>), Variant63(ast::Parameter), Variant64(core::option::Option), Variant65(ast::ExceptHandler), @@ -117,474 +117,477 @@ mod __parse__Top { Variant67((TextSize, ast::ConversionFlag)), Variant68(core::option::Option<(TextSize, ast::ConversionFlag)>), Variant69(StringType), - Variant70(alloc::vec::Vec), - Variant71(core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), - Variant72(ast::Alias), - Variant73(Vec), - Variant74(u32), - Variant75(alloc::vec::Vec), - Variant76((Option, Option)), - Variant77(ast::MatchCase), - Variant78(alloc::vec::Vec), - Variant79(ast::PatternKeyword), - Variant80((ast::Expr, ast::Pattern)), - Variant81(ast::Number), - Variant82(Vec), - Variant83(Vec), - Variant84(Vec<(ast::Expr, ast::Pattern)>), - Variant85(Vec), - Variant86(Vec), - Variant87((Vec, Vec)), - Variant88(core::option::Option), - Variant89(ast::PatternArguments), - Variant90(ast::Comprehension), - Variant91(alloc::vec::Vec), - Variant92(Option), - Variant93(core::option::Option>), - Variant94(Vec), - Variant95(alloc::vec::Vec), - Variant96(ast::Mod), - Variant97(ast::TypeParam), - Variant98(ast::TypeParams), - Variant99(core::option::Option), - Variant100(ast::UnaryOp), - Variant101(core::option::Option<(String, bool)>), + Variant70(ast::FStringFormatSpec), + Variant71(core::option::Option), + Variant72(ast::FStringElement), + Variant73(alloc::vec::Vec), + Variant74(core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), + Variant75(ast::Alias), + Variant76(Vec), + Variant77(u32), + Variant78(alloc::vec::Vec), + Variant79((Option, Option)), + Variant80(ast::MatchCase), + Variant81(alloc::vec::Vec), + Variant82(ast::PatternKeyword), + Variant83((ast::Expr, ast::Pattern)), + Variant84(ast::Number), + Variant85(Vec), + Variant86(Vec), + Variant87(Vec<(ast::Expr, ast::Pattern)>), + Variant88(Vec), + Variant89(Vec), + Variant90((Vec, Vec)), + Variant91(core::option::Option), + Variant92(ast::PatternArguments), + Variant93(ast::Comprehension), + Variant94(alloc::vec::Vec), + Variant95(Option), + Variant96(core::option::Option>), + Variant97(Vec), + Variant98(ast::Mod), + Variant99(Vec), + Variant100(ast::TypeParam), + Variant101(ast::TypeParams), + Variant102(core::option::Option), + Variant103(ast::UnaryOp), + Variant104(core::option::Option<(String, bool)>), } const __ACTION: &[i16] = &[ // State 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, // State 1 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 2 - -768, 0, 0, 0, 0, 0, 0, -768, 0, -768, 0, 0, 0, -768, 0, 0, -768, 0, 0, 0, -768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -768, 0, -768, -768, -768, -768, 0, 0, 0, 0, 0, -768, -768, -768, -768, 0, -768, -768, -768, -768, 0, 0, 0, 0, -768, -768, -768, -768, -768, 0, 0, -768, -768, -768, -768, 0, -768, -768, -768, -768, -768, -768, -768, -768, -768, 0, 0, 0, -768, 0, 0, -768, 0, 0, 0, -768, -768, 0, -768, -768, -768, -768, + -769, 0, 0, 0, 0, 0, 0, -769, 0, -769, 0, 0, 0, -769, 0, 0, -769, 0, 0, 0, -769, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -769, 0, -769, -769, -769, -769, 0, 0, 0, 0, 0, -769, -769, -769, -769, 0, -769, -769, -769, -769, 0, 0, 0, 0, -769, -769, -769, -769, -769, 0, 0, -769, -769, -769, -769, 0, -769, -769, -769, -769, -769, -769, -769, -769, -769, 0, 0, 0, -769, 0, 0, -769, 0, 0, 0, -769, -769, 0, -769, -769, -769, -769, // State 3 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 4 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 5 - -790, -790, -790, 0, -790, -790, -790, 0, -790, 0, 0, -790, -790, 440, -790, -790, 441, -790, 0, 0, 0, 0, 0, -790, -790, -790, 0, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, 0, -790, 0, 0, 0, 0, -790, -790, -790, -790, -790, 0, -790, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, 0, -790, -790, 0, -790, 0, -790, -790, 0, 0, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -791, -791, -791, 0, -791, -791, -791, 0, -791, 0, 0, -791, -791, 440, -791, -791, 441, -791, 0, 0, 0, 0, 0, -791, -791, -791, 0, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, -791, 0, -791, 0, 0, 0, 0, -791, -791, -791, -791, -791, 0, -791, 0, 0, 0, 0, 0, 0, 0, 0, -791, 0, 0, -791, -791, 0, -791, 0, -791, -791, 0, 0, 0, -791, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, -791, -791, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 6 - -248, -248, -248, -248, -248, -248, -248, 25, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 0, 26, 0, -248, -248, -248, -248, -248, 0, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 0, 0, 0, 27, -248, -248, -248, -248, -248, 0, -248, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, 0, -248, -248, 0, -248, 0, -248, -248, 0, 0, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -248, -248, -248, -248, -248, -248, -248, 26, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 0, 27, 0, -248, -248, -248, -248, -248, 0, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 0, 0, 0, 28, -248, -248, -248, -248, -248, 0, -248, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, 0, -248, -248, 0, -248, 0, -248, -248, 0, 0, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 7 - -304, -304, 443, 0, -304, 0, -304, 0, -304, 0, 0, -304, -304, 0, -304, -304, 0, -304, 0, 0, 0, 0, 0, -304, -304, -304, 0, -304, 444, 0, -304, 445, -304, 446, 447, 448, 0, -304, 0, 0, -304, 0, 0, 0, 0, -304, 0, -304, -304, -304, 0, -304, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 0, -304, -304, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -304, -304, 443, 0, -304, 0, -304, 0, -304, 0, 0, -304, -304, 0, -304, -304, 0, -304, 0, 0, 0, 0, 0, -304, -304, -304, 0, -304, 444, 0, -304, 445, -304, 446, 447, 448, 0, -304, 0, 0, -304, 0, 0, 0, 0, -304, 0, -304, -304, -304, 0, -304, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 0, -304, -304, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 8 453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 9 -155, -155, -155, 0, -155, -155, -155, 0, -155, 0, 0, -155, -155, 0, -155, -155, 0, -155, 0, 0, 0, 0, 0, -155, -155, -155, 0, -155, -155, 455, -155, -155, -155, -155, -155, -155, 456, -155, -155, 0, -155, 0, 0, 0, 0, -155, -155, -155, -155, -155, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, -155, -155, 0, -155, 0, -155, -155, 0, 0, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 10 - -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 0, -183, 0, -183, -183, -183, -183, -183, 0, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 0, 0, 0, -183, -183, -183, -183, -183, -183, 0, -183, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, 0, -183, -183, 0, -183, 0, -183, -183, 0, 0, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, -183, -183, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, + -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, 0, -836, 0, -836, -836, -836, -836, -836, 0, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, -836, 0, 0, 0, -836, -836, -836, -836, -836, -836, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, -836, -836, 0, -836, 0, -836, -836, 0, 0, 0, -836, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, -836, -836, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, // State 11 -169, -169, -169, 458, -169, -169, -169, 0, -169, 459, 0, -169, -169, -169, -169, -169, -169, -169, 0, 0, 0, 460, 461, -169, -169, -169, 0, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 462, -169, 0, 0, 0, 0, -169, -169, -169, -169, -169, 0, -169, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, 0, -169, -169, 0, -169, 0, -169, -169, 0, 0, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 12 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, 0, -837, 0, -837, -837, -837, -837, -837, 0, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, -837, 0, 0, 0, -837, -837, -837, -837, -837, -837, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, -837, -837, 0, -837, 0, -837, -837, 0, 0, 0, -837, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, -837, -837, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, // State 13 - 0, 0, 0, 0, 0, 0, 0, 14, 471, 15, 39, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 14 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 472, 16, 40, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 15 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 479, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 16 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 480, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 17 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 18 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 19 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 48, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 494, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 20 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 497, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 49, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 495, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 21 - 524, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 525, 17, 526, 0, 57, 527, 58, 59, 0, 0, 0, 0, 60, 61, 62, 63, 64, 0, 0, 18, 65, 66, 19, 0, 528, 67, 68, 529, 69, 70, 71, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, // State 22 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 525, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 526, 18, 527, 0, 58, 528, 59, 60, 0, 0, 0, 0, 61, 62, 63, 64, 65, 0, 0, 19, 66, 67, 20, 0, 529, 68, 69, 530, 70, 71, 72, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 23 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 24 - 0, 0, 0, 0, 0, 0, 0, 14, 535, 76, 77, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 25 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 536, 77, 78, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 26 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 27 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 28 - -303, -303, 443, 0, -303, 0, -303, 0, -303, 0, 0, -303, -303, 0, -303, -303, 0, -303, 0, 0, 0, 0, 0, -303, -303, -303, 0, -303, 444, 0, -303, 445, -303, 446, 447, 448, 0, -303, 0, 0, -303, 0, 0, 0, 0, -303, 0, -303, -303, -303, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, -303, 0, 0, -303, -303, 0, -303, 0, 449, 450, 0, 0, 0, 451, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 29 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -303, -303, 443, 0, -303, 0, -303, 0, -303, 0, 0, -303, -303, 0, -303, -303, 0, -303, 0, 0, 0, 0, 0, -303, -303, -303, 0, -303, 444, 0, -303, 445, -303, 446, 447, 448, 0, -303, 0, 0, -303, 0, 0, 0, 0, -303, 0, -303, -303, -303, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, -303, 0, 0, -303, -303, 0, -303, 0, 449, 450, 0, 0, 0, 451, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 30 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 31 - -426, -426, 0, 0, -426, 0, -426, 14, -426, 15, 0, -426, -426, 425, -426, 0, 426, -426, 0, 0, 427, 0, 0, -426, -426, -426, 0, -426, 0, 0, -426, 0, -426, 0, 0, 0, 0, -426, 0, 0, -426, 428, 429, 430, 16, 0, 0, -426, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, -426, -426, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 32 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -426, -426, 0, 0, -426, 0, -426, 15, -426, 16, 0, -426, -426, 425, -426, 0, 426, -426, 0, 0, 427, 0, 0, -426, -426, -426, 0, -426, 0, 0, -426, 0, -426, 0, 0, 0, 0, -426, 0, 0, -426, 428, 429, 430, 17, 0, 0, -426, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, -426, -426, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 33 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 34 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 35 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 36 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 37 - 0, 0, 0, 0, 0, 0, 0, 0, 556, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 38 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 39 - -947, -947, 0, 0, 0, 0, 0, 14, -947, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, -947, 0, -947, 0, 0, 0, 0, -947, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, -947, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 40 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -950, -950, 0, 0, 0, 0, 0, 15, -950, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, -950, 0, -950, 0, 0, 0, 0, -950, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, -950, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 41 - -247, -247, -247, -247, -247, -247, -247, 25, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 0, 26, 0, -247, -247, -247, -247, -247, 0, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 0, 0, 0, 27, -247, -247, -247, -247, -247, 0, -247, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, 0, -247, -247, 0, -247, 0, -247, -247, 0, 0, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 42 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, -723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + -247, -247, -247, -247, -247, -247, -247, 26, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 0, 27, 0, -247, -247, -247, -247, -247, 0, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 0, 0, 0, 28, -247, -247, -247, -247, -247, 0, -247, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, 0, -247, -247, 0, -247, 0, -247, -247, 0, 0, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 43 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -460, 0, 0, 0, 0, 0, 0, 0, 0, 0, -460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 44 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 93, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -460, 0, 0, 0, 0, 0, 0, 0, 0, 0, -460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 45 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 94, 434, 0, 435, 436, // State 46 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 47 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 48 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 574, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 49 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 575, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, // State 50 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 51 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 579, 0, 0, 0, 98, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 52 - -304, 0, 443, 0, -304, 0, -304, 0, 0, 0, 0, -304, -304, 0, -304, -304, 0, -304, 0, 0, 0, 0, 0, -304, -304, -304, 0, -304, 444, 0, -304, 445, -304, 446, 447, 448, 0, -304, 581, 0, -304, 0, 0, 0, 0, 0, 0, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 580, 0, 0, 0, 99, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 53 - -358, 0, 0, 0, 583, 0, 584, 0, 0, 0, 0, 585, 586, 0, 587, 0, 0, 588, 0, 0, 0, 0, 0, 589, 590, 0, 0, -358, 0, 0, 591, 0, 102, 0, 0, 0, 0, 592, 0, 0, 593, 0, 0, 0, 0, 0, 0, 594, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 595, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -304, 0, 443, 0, -304, 0, -304, 0, 0, 0, 0, -304, -304, 0, -304, -304, 0, -304, 0, 0, 0, 0, 0, -304, -304, -304, 0, -304, 444, 0, -304, 445, -304, 446, 447, 448, 0, -304, 582, 0, -304, 0, 0, 0, 0, 0, 0, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 54 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -358, 0, 0, 0, 584, 0, 585, 0, 0, 0, 0, 586, 587, 0, 588, 0, 0, 589, 0, 0, 0, 0, 0, 590, 591, 0, 0, -358, 0, 0, 592, 0, 103, 0, 0, 0, 0, 593, 0, 0, 594, 0, 0, 0, 0, 0, 0, 595, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 55 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 56 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 58 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 59 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 60 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 611, 612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 61 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 612, 613, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, // State 62 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 63 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 64 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, // State 65 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 66 - -775, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 67 - -394, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -776, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 68 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + -394, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 69 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 70 - 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 653, 654, 655, 124, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 71 - -154, -154, -154, 0, -154, -154, -154, 0, -154, 0, 0, -154, -154, 0, -154, -154, 0, -154, 0, 0, 0, 0, 0, -154, -154, -154, 0, -154, -154, 455, -154, -154, -154, -154, -154, -154, 456, -154, -154, 0, -154, 0, 0, 0, 0, -154, -154, -154, -154, -154, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, -154, -154, 0, -154, 0, -154, -154, 0, 0, 0, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, 124, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 72 - -168, -168, -168, 458, -168, -168, -168, 0, -168, 459, 0, -168, -168, -168, -168, -168, -168, -168, 0, 0, 0, 460, 461, -168, -168, -168, 0, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 462, -168, 0, 0, 0, 0, -168, -168, -168, -168, -168, 0, -168, 0, 0, 0, 0, 0, 0, 0, 0, -168, 0, 0, -168, -168, 0, -168, 0, -168, -168, 0, 0, 0, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -154, -154, -154, 0, -154, -154, -154, 0, -154, 0, 0, -154, -154, 0, -154, -154, 0, -154, 0, 0, 0, 0, 0, -154, -154, -154, 0, -154, -154, 455, -154, -154, -154, -154, -154, -154, 456, -154, -154, 0, -154, 0, 0, 0, 0, -154, -154, -154, -154, -154, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, -154, -154, 0, -154, 0, -154, -154, 0, 0, 0, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 73 - 0, 0, 0, 0, 0, 0, 0, 14, 657, 76, 77, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -168, -168, -168, 458, -168, -168, -168, 0, -168, 459, 0, -168, -168, -168, -168, -168, -168, -168, 0, 0, 0, 460, 461, -168, -168, -168, 0, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 462, -168, 0, 0, 0, 0, -168, -168, -168, -168, -168, 0, -168, 0, 0, 0, 0, 0, 0, 0, 0, -168, 0, 0, -168, -168, 0, -168, 0, -168, -168, 0, 0, 0, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 74 - 0, 0, 0, 0, 0, 0, 0, 0, -418, 0, 0, 0, 0, 0, 0, -418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 659, 77, 78, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 75 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, -418, 0, 0, 0, 0, 0, 0, -418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 76 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 77 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, -850, 426, 0, 0, 0, 427, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -850, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 78 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, -849, 426, 0, 0, 0, 427, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, -849, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 79 - -789, -789, -789, 0, -789, -789, -789, 0, -789, 0, 0, -789, -789, 440, -789, -789, 441, -789, 0, 0, 0, 0, 0, -789, -789, -789, 0, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, 0, -789, 0, 0, 0, 0, -789, -789, -789, -789, -789, 0, -789, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, 0, -789, -789, 0, -789, 0, -789, -789, 0, 0, 0, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 80 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -790, -790, -790, 0, -790, -790, -790, 0, -790, 0, 0, -790, -790, 440, -790, -790, 441, -790, 0, 0, 0, 0, 0, -790, -790, -790, 0, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, 0, -790, 0, 0, 0, 0, -790, -790, -790, -790, -790, 0, -790, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, 0, -790, -790, 0, -790, 0, -790, -790, 0, 0, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 81 - 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 82 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 83 - 0, 0, 0, 0, 0, 0, 0, 14, 672, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 84 - 0, 0, 0, 0, 0, 0, 0, 14, 675, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 674, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 85 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 677, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 86 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -465, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 87 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, -674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, -465, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 88 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 140, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, -675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 89 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 140, 434, 0, 435, 436, // State 90 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, -722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 91 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, -723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 92 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -716, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 93 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 48, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, -329, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 94 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, -787, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 49, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, -329, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 95 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, -788, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 96 - 0, 695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 97 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 99 - -359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -359, 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 100 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -359, 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 101 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 704, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 102 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 706, 435, 436, // State 103 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 104 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 105 - 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 653, 654, 655, 124, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 106 - 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, 656, 657, 124, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 107 - 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 108 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 611, 612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 109 - -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 161, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 612, 613, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, // State 110 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 161, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 111 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 112 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 113 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 114 - 0, 0, -790, 0, 0, -790, 0, 0, 0, 0, 0, 0, 0, 440, 0, -790, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, -790, 0, -790, 0, -790, -790, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, -790, -790, 0, 0, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 115 - 0, 0, -248, -248, 0, -248, 0, 25, 0, -248, -248, 0, 0, -248, 0, -248, -248, 0, 0, 175, 0, -248, -248, 0, 0, 0, 0, 0, -248, -248, 0, -248, 0, -248, -248, -248, -248, 0, 0, -248, 0, 0, 0, 0, 176, 0, -248, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, -248, -248, 0, 0, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -791, 0, 0, -791, 0, 0, 0, 0, 0, 0, 0, 440, 0, -791, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -791, -791, 0, -791, 0, -791, -791, -791, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, -791, 0, -791, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -791, 0, -791, -791, 0, 0, 0, -791, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 116 - 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 0, 0, 445, 0, 446, 447, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -248, -248, 0, -248, 0, 26, 0, -248, -248, 0, 0, -248, 0, -248, -248, 0, 0, 175, 0, -248, -248, 0, 0, 0, 0, 0, -248, -248, 0, -248, 0, -248, -248, -248, -248, 0, 0, -248, 0, 0, 0, 0, 176, 0, -248, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, -248, -248, 0, 0, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 117 - 0, 0, -155, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 455, 0, -155, 0, -155, -155, -155, 456, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, -155, -155, 0, 0, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 0, 0, 445, 0, 446, 447, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 118 - 0, 0, -183, -183, 0, -183, 0, -183, 0, -183, -183, 0, 0, -183, 0, -183, -183, 0, 0, -183, 0, -183, -183, 0, 0, -212, 0, 0, -183, -183, 0, -183, 0, -183, -183, -183, -183, 0, 0, -183, 0, 0, 0, 0, -183, 0, -183, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, -183, -183, 0, 0, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, + 0, 0, -155, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 455, 0, -155, 0, -155, -155, -155, 456, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, -155, -155, 0, 0, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 119 0, 0, -169, 458, 0, -169, 0, 0, 0, 459, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, 0, 460, 461, 0, 0, 0, 0, 0, -169, -169, 0, -169, 0, -169, -169, -169, -169, 0, 0, 462, 0, 0, 0, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 120 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 122 - 0, 0, 0, 0, 0, 0, 0, 14, 727, 15, 190, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 729, 16, 190, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 123 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 729, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 731, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 124 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 125 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 126 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 48, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 733, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 49, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 735, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 127 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 128 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -852, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, -851, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 129 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, -848, 426, 0, 0, 0, 427, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -848, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, -847, 426, 0, 0, 0, 427, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, -847, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 130 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -853, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, -852, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 131 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 132 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, -802, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -802, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, -803, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, -803, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 133 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 134 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 135 - 0, 0, 0, 0, 0, 0, 0, 14, 745, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 747, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 136 - 0, 0, 0, 0, 0, 0, 0, 0, 747, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 137 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -692, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -693, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 138 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 139 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 140 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 141 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -714, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 142 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 143 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, -368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, -368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, // State 144 - 0, 695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 146 - 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 147 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 148 - -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 149 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 150 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 151 - 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 152 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 153 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 154 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 155 - 0, 0, 0, 0, 0, 0, 0, 0, 781, 217, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 783, 217, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 156 - -353, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + -353, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 157 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 158 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 159 - 0, 0, 0, 0, 0, 0, 0, 219, 0, 787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 219, 0, 789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 161 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 162 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 164 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, // State 165 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 166 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 167 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 168 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 169 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 170 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 171 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 172 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 173 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 175 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 176 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 177 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, -305, 0, 0, 444, 0, 0, 445, 0, 446, 447, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, 0, 449, 450, 0, 0, 0, 451, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 178 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 179 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 180 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 181 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 182 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 183 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 184 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 185 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 186 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 187 - 0, 0, 0, 0, 0, 0, 0, 0, 820, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 822, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 188 - 0, 0, 0, 0, 0, 0, 0, 0, 823, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 825, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 189 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 190 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 191 - 0, 0, -247, -247, 0, -247, 0, 25, 0, -247, -247, 0, 0, -247, 0, -247, -247, 0, 0, 26, 0, -247, -247, 0, 0, -249, 0, 0, -247, -247, 0, -247, 0, -247, -247, -247, -247, 0, 0, -247, 0, 0, 0, 0, 27, 0, -247, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, -247, -247, 0, 0, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -247, -247, 0, -247, 0, 26, 0, -247, -247, 0, 0, -247, 0, -247, -247, 0, 0, 27, 0, -247, -247, 0, 0, -249, 0, 0, -247, -247, 0, -247, 0, -247, -247, -247, -247, 0, 0, -247, 0, 0, 0, 0, 28, 0, -247, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, -247, -247, 0, 0, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 192 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 193 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 194 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 195 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 196 - 0, 0, 0, 0, 0, 0, 0, 14, 834, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 836, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 197 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, -689, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, -690, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 198 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -665, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 199 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 200 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -716, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 201 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, -369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, -369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, // State 202 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 203 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 204 - 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 205 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 206 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 207 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 208 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 209 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 210 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 211 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 212 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 213 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 214 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 215 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 216 - 0, 0, 0, 0, 0, 0, 0, 0, -645, 0, 0, 0, 0, 0, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -646, 0, 0, 0, 0, 0, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 217 0, 0, 0, 0, 0, 0, 0, 0, -458, 0, 0, 0, 0, 0, 0, -458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 218 @@ -592,87 +595,87 @@ mod __parse__Top { // State 219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 220 - -432, 0, 0, 0, 0, 0, 0, -432, 0, -432, 0, 0, 0, -432, 0, 0, -432, 0, 0, 0, -432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -432, 0, -432, -432, -432, -432, 0, 0, 0, 0, 0, -432, -432, -432, -432, 0, -432, -432, -432, -432, 261, 868, 0, 0, -432, -432, -432, -432, -432, 0, 0, -432, -432, -432, -432, 0, -432, -432, -432, -432, -432, -432, -432, -432, -432, 0, 0, 0, -432, -432, 0, -432, 0, 0, 0, -432, -432, 0, -432, -432, -432, -432, + -432, 0, 0, 0, 0, 0, 0, -432, 0, -432, 0, 0, 0, -432, 0, 0, -432, 0, 0, 0, -432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -432, 0, -432, -432, -432, -432, 0, 0, 0, 0, 0, -432, -432, -432, -432, 0, -432, -432, -432, -432, 261, 870, 0, 0, -432, -432, -432, -432, -432, 0, 0, -432, -432, -432, -432, 0, -432, -432, -432, -432, -432, -432, -432, -432, -432, 0, 0, 0, -432, -432, 0, -432, 0, 0, 0, -432, -432, 0, -432, -432, -432, -432, // State 221 - -888, 0, 0, 0, 0, 0, 0, -888, 0, -888, 0, 0, 0, -888, 0, 0, -888, 0, 0, 0, -888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -888, 0, -888, -888, -888, -888, 0, 0, 0, 0, 0, -888, -888, -888, -888, 0, -888, -888, -888, -888, 0, 875, 265, 876, -888, -888, -888, -888, -888, 0, 0, -888, -888, -888, -888, 0, -888, -888, -888, -888, -888, -888, -888, -888, -888, 0, 0, 0, -888, -888, 0, -888, 0, 0, 0, -888, -888, 0, -888, -888, -888, -888, + -887, 0, 0, 0, 0, 0, 0, -887, 0, -887, 0, 0, 0, -887, 0, 0, -887, 0, 0, 0, -887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -887, 0, -887, -887, -887, -887, 0, 0, 0, 0, 0, -887, -887, -887, -887, 0, -887, -887, -887, -887, 0, 877, 265, 878, -887, -887, -887, -887, -887, 0, 0, -887, -887, -887, -887, 0, -887, -887, -887, -887, -887, -887, -887, -887, -887, 0, 0, 0, -887, -887, 0, -887, 0, 0, 0, -887, -887, 0, -887, -887, -887, -887, // State 222 - -892, 0, 0, 0, 0, 0, 0, -892, 0, -892, 0, 0, 0, -892, 0, 0, -892, 0, 0, 0, -892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -892, 0, -892, -892, -892, -892, 0, 0, 0, 0, 0, -892, -892, -892, -892, 0, -892, -892, -892, -892, 0, 878, 879, 880, -892, -892, -892, -892, -892, 0, 0, -892, -892, -892, -892, 0, -892, -892, -892, -892, -892, -892, -892, -892, -892, 0, 0, 0, -892, -892, 0, -892, 0, 0, 0, -892, -892, 0, -892, -892, -892, -892, + -891, 0, 0, 0, 0, 0, 0, -891, 0, -891, 0, 0, 0, -891, 0, 0, -891, 0, 0, 0, -891, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -891, 0, -891, -891, -891, -891, 0, 0, 0, 0, 0, -891, -891, -891, -891, 0, -891, -891, -891, -891, 0, 880, 881, 882, -891, -891, -891, -891, -891, 0, 0, -891, -891, -891, -891, 0, -891, -891, -891, -891, -891, -891, -891, -891, -891, 0, 0, 0, -891, -891, 0, -891, 0, 0, 0, -891, -891, 0, -891, -891, -891, -891, // State 223 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 266, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 266, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 224 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 525, 17, 526, 0, 57, 527, 58, 59, 0, 0, 0, 0, 60, 61, 62, 63, 64, 0, 0, 18, 65, 66, 19, 0, 528, 67, 68, 529, 69, 70, 71, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 526, 18, 527, 0, 58, 528, 59, 60, 0, 0, 0, 0, 61, 62, 63, 64, 65, 0, 0, 19, 66, 67, 20, 0, 529, 68, 69, 530, 70, 71, 72, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 225 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 226 0, 0, -154, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -156, 0, 0, -154, 455, 0, -154, 0, -154, -154, -154, 456, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, -154, -154, 0, 0, 0, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 227 0, 0, -168, 458, 0, -168, 0, 0, 0, 459, 0, 0, 0, -168, 0, -168, -168, 0, 0, 0, 0, 460, 461, 0, 0, -170, 0, 0, -168, -168, 0, -168, 0, -168, -168, -168, -168, 0, 0, 462, 0, 0, 0, 0, 0, 0, -168, 0, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, 0, -168, -168, 0, 0, 0, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 228 - 0, 0, -789, 0, 0, -789, 0, 0, 0, 0, 0, 0, 0, 440, 0, -789, 441, 0, 0, 0, 0, 0, 0, 0, 0, -791, 0, 0, -789, -789, 0, -789, 0, -789, -789, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, -789, -789, 0, 0, 0, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -790, 0, 0, -790, 0, 0, 0, 0, 0, 0, 0, 440, 0, -790, 441, 0, 0, 0, 0, 0, 0, 0, 0, -792, 0, 0, -790, -790, 0, -790, 0, -790, -790, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, -790, -790, 0, 0, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 229 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 230 - 0, 0, 0, 0, 0, 0, 0, 14, 890, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 892, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 231 - 0, 0, 0, 0, 0, 0, 0, 14, 892, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 894, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 232 - 0, 0, 0, 0, 0, 0, 0, 14, 894, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 896, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 233 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 234 - 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 235 - 0, 0, 0, 0, 0, 0, 0, 14, 900, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 902, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 236 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 237 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -662, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 238 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 239 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, -693, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, -694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 240 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 241 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 242 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 243 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 244 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 245 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 246 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 247 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 248 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 249 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 250 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 251 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 252 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 253 - 0, 0, 0, 0, 0, 0, 0, 0, -596, 292, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -597, 292, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 254 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 255 - 0, 0, 0, 0, 0, 0, 0, 0, -644, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -645, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 256 - 0, 0, 0, 0, 0, 0, 0, 0, -637, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -638, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 257 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 260 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 262 @@ -680,329 +683,329 @@ mod __parse__Top { // State 263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 264 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 265 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 266 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 267 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 268 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 269 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 525, 17, 526, 0, 57, 527, 58, 59, 0, 0, 0, 0, 60, 61, 62, 63, 64, 0, 0, 18, 65, 66, 19, 0, 528, 67, 68, 529, 69, 70, 71, 40, 20, 0, 0, 0, 431, 946, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 526, 18, 527, 0, 58, 528, 59, 60, 0, 0, 0, 0, 61, 62, 63, 64, 65, 0, 0, 19, 66, 67, 20, 0, 529, 68, 69, 530, 70, 71, 72, 41, 21, 0, 0, 0, 431, 948, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 270 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 271 - 0, 0, 0, 0, 0, 0, 0, 14, 948, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 950, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 272 - 0, 0, 0, 0, 0, 0, 0, 0, 950, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 952, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 273 - 0, 0, 0, 0, 0, 0, 0, 0, 952, 0, 0, 0, 0, 0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 954, 0, 0, 0, 0, 0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 274 - 0, 0, 0, 0, 0, 0, 0, 14, 953, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 955, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 275 - 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 276 - 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 277 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 278 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -669, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 279 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, -694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, -695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 280 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 0, 0, 0, 0, 0, 0, 0, 0, 0, -690, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 0, 0, 0, 0, 0, 0, 0, 0, 0, -691, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 281 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 282 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 283 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 284 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 285 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 286 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 287 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 288 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 289 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 290 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 291 - 0, 0, 0, 0, 0, 0, 0, 0, -614, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -615, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 292 - 0, 0, 0, 0, 0, 0, 0, 0, -624, 0, 0, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -625, 0, 0, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 293 - 0, 0, 0, 0, 0, 0, 0, 0, -639, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -640, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 294 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 295 - 0, 0, 0, 0, 0, 0, 0, 0, -636, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -637, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 296 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 297 - 0, 0, 0, 0, 0, 0, 0, 0, 983, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 985, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 298 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 299 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 301 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 987, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 989, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 302 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 303 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 304 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1009, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 305 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 306 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 307 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 308 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 309 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 311 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 312 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 313 - 0, 0, 0, 0, 0, 0, 0, 14, 1024, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 1025, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 314 - 0, 0, 0, 0, 0, 0, 0, 14, 1026, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 1027, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 315 - 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 316 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, -691, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, -692, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 317 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 318 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 319 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 320 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 321 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 322 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 323 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 324 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 325 - 0, 0, 0, 0, 0, 0, 0, 0, -611, 0, 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -612, 0, 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 326 - 0, 0, 0, 0, 0, 0, 0, 0, -587, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -588, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 327 - 0, 0, 0, 0, 0, 0, 0, 0, -597, 358, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -598, 359, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 328 - 0, 0, 0, 0, 0, 0, 0, 0, -638, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -639, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 329 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 330 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 331 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 332 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1049, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 333 - 0, 0, 0, 0, 0, 0, 0, 362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 334 - 0, 0, 0, 0, 0, 0, 0, 362, -919, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, 364, 0, 0, 0, 0, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -919, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 363, -922, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, 365, 0, 0, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -922, 0, -922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 335 0, 0, 0, 0, 0, 0, 0, 0, -472, 0, 0, 0, 0, 440, 0, -472, 441, 0, 0, 0, 0, 0, 0, 0, 0, -472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -472, 0, 0, 0, -472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -472, 0, -472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 336 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 337 0, 0, 0, 0, 0, 0, 0, 0, -474, 0, 0, 0, 0, 0, 0, -474, 0, 0, 0, 0, 0, 0, 0, 0, 0, -474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -474, 0, 0, 0, -474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -474, 0, -474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, // State 338 - 0, 0, 0, 0, 0, 0, 0, 339, 1054, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, // State 339 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 340, 1056, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 340 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 341 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 1058, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 0, 0, // State 342 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 376, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1066, 1067, 1068, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1069, 0, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 1060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 343 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1070, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 376, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1069, 1070, 1071, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1072, 0, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 344 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 345 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 346 - 0, 0, 0, 0, 0, 0, 0, 14, 1079, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 347 - 0, 0, 0, 0, 0, 0, 0, 14, 1080, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 1082, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 348 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 1083, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 349 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 350 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -669, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -665, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 351 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 352 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 353 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 354 - 0, 0, 0, 0, 0, 0, 0, 0, -593, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 355 - 0, 0, 0, 0, 0, 0, 0, 0, -584, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -594, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 356 - 0, 0, 0, 0, 0, 0, 0, 0, -598, 382, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -585, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 357 - 0, 0, 0, 0, 0, 0, 0, 0, -615, 0, 0, 0, 0, 0, 0, 384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -599, 382, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 358 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, -616, 0, 0, 0, 0, 0, 0, 384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 359 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 360 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 361 - 0, 0, 0, 0, 0, 0, 0, 339, 1105, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 362 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 340, 1108, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 363 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 0, 0, - // State 365 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + // State 365 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 0, 0, // State 366 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 367 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 368 - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 369 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 370 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 371 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, -762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 372 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 1119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 373 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 440, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 1122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 374 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 440, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 375 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 376 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 377 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 378 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 379 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 380 - 0, 0, 0, 0, 0, 0, 0, 0, -590, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -591, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 381 - 0, 0, 0, 0, 0, 0, 0, 0, -616, 0, 0, 0, 0, 0, 0, 392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -617, 0, 0, 0, 0, 0, 0, 392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 382 - 0, 0, 0, 0, 0, 0, 0, 0, -612, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -613, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 383 - 0, 0, 0, 0, 0, 0, 0, 0, -588, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -589, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 384 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 385 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 386 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1066, 1067, 1068, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1149, 0, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1069, 1070, 1071, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1152, 0, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 387 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 388 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 389 - 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, + 719, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 17, 0, 0, 0, 0, 0, 57, 0, 18, 527, 0, 0, 528, 0, 60, 0, 0, 0, 0, 0, 62, 63, 0, 65, 0, 0, 19, 0, 67, 20, 0, 529, 68, 69, 0, 70, 0, 0, 41, 21, 0, 0, 0, 431, 0, 0, 22, 0, 0, 0, 432, 433, 0, 434, 531, 435, 436, // State 390 - 0, 0, 0, 0, 0, 0, 0, 0, -613, 0, 0, 0, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -614, 0, 0, 0, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 391 - 0, 0, 0, 0, 0, 0, 0, 0, -589, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -590, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 392 - 0, 0, 0, 0, 0, 0, 0, 0, -594, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -595, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 393 - 0, 0, 0, 0, 0, 0, 0, 0, -585, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -586, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 394 - 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 0, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 395 - 0, 0, 0, 0, 0, 0, 0, 0, 1165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 396 - 0, 0, 0, 0, 0, 0, 0, 339, 1168, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, + 0, 0, 0, 0, 0, 0, 0, 340, 1171, 341, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1007, 1008, 1009, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 398 - 0, 0, 0, 0, 0, 0, 0, 0, -595, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -596, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 399 - 0, 0, 0, 0, 0, 0, 0, 0, -586, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -587, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 400 - 0, 0, 0, 0, 0, 0, 0, 0, -591, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, - // State 401 0, 0, 0, 0, 0, 0, 0, 0, -592, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + // State 401 + 0, 0, 0, 0, 0, 0, 0, 0, -593, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 402 - 0, 0, 0, 0, 0, 0, 0, 0, 1185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 403 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 404 - -943, -943, -943, 0, -943, 23, -943, 0, -943, 0, 0, -943, -943, 0, -943, -943, 0, -943, 0, 0, 0, 0, 0, -943, -943, -943, 0, -943, -943, 0, -943, -943, -943, -943, -943, -943, 0, -943, -943, 0, -943, 0, 0, 0, 0, -943, -943, -943, -943, -943, 0, -943, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, 0, -943, -943, 0, -943, 0, -943, -943, 0, 0, 0, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -946, -946, -946, 0, -946, 24, -946, 0, -946, 0, 0, -946, -946, 0, -946, -946, 0, -946, 0, 0, 0, 0, 0, -946, -946, -946, 0, -946, -946, 0, -946, -946, -946, -946, -946, -946, 0, -946, -946, 0, -946, 0, 0, 0, 0, -946, -946, -946, -946, -946, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, 0, -946, -946, 0, -946, 0, -946, -946, 0, 0, 0, -946, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, -946, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 405 - -559, -559, 0, 0, -559, 0, -559, 0, -559, 0, 0, -559, -559, 0, -559, -559, 0, -559, 0, 0, 0, 0, 0, -559, -559, -559, 0, -559, 0, 0, -559, 0, -559, 0, 0, 0, 0, -559, 0, 0, -559, 0, 0, 0, 0, -559, 0, -559, 0, -559, 0, -559, 0, 0, 0, 0, 0, 0, 0, 0, -559, 0, 0, -559, -559, 0, -559, 0, 0, 0, 0, 0, 0, 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -559, -559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -560, -560, 0, 0, -560, 0, -560, 0, -560, 0, 0, -560, -560, 0, -560, -560, 0, -560, 0, 0, 0, 0, 0, -560, -560, -560, 0, -560, 0, 0, -560, 0, -560, 0, 0, 0, 0, -560, 0, 0, -560, 0, 0, 0, 0, -560, 0, -560, 0, -560, 0, -560, 0, 0, 0, 0, 0, 0, 0, 0, -560, 0, 0, -560, -560, 0, -560, 0, 0, 0, 0, 0, 0, 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -560, -560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 406 -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 0, -239, 0, -239, -239, -239, -239, -239, 0, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 0, 0, 0, -239, -239, -239, -239, -239, -239, 0, -239, 0, 0, 0, 0, 0, 0, 0, 0, -239, 0, 0, -239, -239, 0, -239, 0, -239, -239, 0, 0, 0, -239, -239, 0, 0, 0, 0, 0, 0, 0, 0, 0, -239, -239, -239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 407 - -765, -765, -765, -765, -765, -765, -765, 0, -765, -765, 28, -765, -765, -765, -765, -765, -765, -765, 0, 0, 0, -765, -765, -765, -765, -765, 0, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, 0, 0, 0, 0, -765, -765, -765, -765, -765, 0, -765, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, 0, -765, -765, 0, -765, 0, -765, -765, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -766, -766, -766, -766, -766, -766, -766, 0, -766, -766, 29, -766, -766, -766, -766, -766, -766, -766, 0, 0, 0, -766, -766, -766, -766, -766, 0, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, -766, 0, 0, 0, 0, -766, -766, -766, -766, -766, 0, -766, 0, 0, 0, 0, 0, 0, 0, 0, -766, 0, 0, -766, -766, 0, -766, 0, -766, -766, 0, 0, 0, -766, -766, 0, 0, 0, 0, 0, 0, 0, 0, 0, -766, -766, -766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 408 - -515, -515, 0, 0, -515, 0, -515, 0, -515, 0, 0, -515, -515, 0, -515, -515, 0, -515, 0, 0, 0, 0, 0, -515, -515, -515, 0, -515, 0, 0, -515, 0, -515, 0, 0, 0, 0, -515, 0, 0, -515, 0, 0, 0, 0, -515, 0, -515, -515, -515, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, -515, -515, 0, -515, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -516, -516, 0, 0, -516, 0, -516, 0, -516, 0, 0, -516, -516, 0, -516, -516, 0, -516, 0, 0, 0, 0, 0, -516, -516, -516, 0, -516, 0, 0, -516, 0, -516, 0, 0, 0, 0, -516, 0, 0, -516, 0, 0, 0, 0, -516, 0, -516, -516, -516, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, -516, -516, 0, -516, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 409 - -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, 0, -839, 0, -839, -839, -839, -839, -839, 0, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, 0, 0, 0, -839, -839, -839, -839, -839, -839, 0, -839, 0, 0, 0, 0, 0, 0, 0, 0, -839, 0, 0, -839, -839, 0, -839, 0, -839, -839, 0, 0, 0, -839, -839, 0, 0, 0, 0, 0, 0, 0, 0, 0, -839, -839, -839, 0, 0, 0, -839, 0, 0, 0, 0, 0, 0, 0, 0, 0, -839, + -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, 0, -840, 0, -840, -840, -840, -840, -840, 0, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, 0, 0, 0, -840, -840, -840, -840, -840, -840, 0, -840, 0, 0, 0, 0, 0, 0, 0, 0, -840, 0, 0, -840, -840, 0, -840, 0, -840, -840, 0, 0, 0, -840, -840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -840, -840, -840, 0, 0, 0, -840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -840, // State 410 - -861, -861, -861, -861, -861, -861, -861, 0, -861, -861, 0, -861, -861, -861, -861, -861, -861, -861, 0, 0, 0, -861, -861, -861, -861, -861, 0, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, 0, 0, 0, 0, -861, -861, -861, -861, -861, 0, -861, 0, 0, 0, 0, 0, 0, 0, 0, -861, 0, 0, -861, -861, 0, -861, 0, -861, -861, 0, 0, 0, -861, -861, 0, 0, 0, 0, 0, 0, 0, 0, 0, -861, -861, -861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -860, -860, -860, -860, -860, -860, -860, 0, -860, -860, 0, -860, -860, -860, -860, -860, -860, -860, 0, 0, 0, -860, -860, -860, -860, -860, 0, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, 0, 0, 0, 0, -860, -860, -860, -860, -860, 0, -860, 0, 0, 0, 0, 0, 0, 0, 0, -860, 0, 0, -860, -860, 0, -860, 0, -860, -860, 0, 0, 0, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, -860, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 411 -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 0, -185, 0, -185, -185, -185, -185, -185, 0, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 0, 0, 0, -185, -185, -185, -185, -185, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, -185, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 412 - -866, -866, 0, 0, -866, 0, -866, 0, -866, 0, 0, -866, -866, 0, -866, -866, 0, -866, 0, 0, 0, 0, 0, -866, -866, -866, 0, -866, 0, 0, -866, 0, -866, 0, 0, 0, 0, -866, 0, 0, -866, 0, 0, 0, 0, -866, 0, -866, 0, -866, 0, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -865, -865, 0, 0, -865, 0, -865, 0, -865, 0, 0, -865, -865, 0, -865, -865, 0, -865, 0, 0, 0, 0, 0, -865, -865, -865, 0, -865, 0, 0, -865, 0, -865, 0, 0, 0, 0, -865, 0, 0, -865, 0, 0, 0, 0, -865, 0, -865, 0, -865, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 413 -159, -159, 0, 0, -159, 0, -159, 0, -159, 0, 0, -159, -159, 0, -159, -159, 0, -159, 0, 0, 0, 0, 0, -159, -159, -159, 0, -159, 0, 0, -159, 0, -159, 0, 0, 0, 0, -159, 0, 0, -159, 0, 0, 0, 0, -159, 0, -159, 454, -159, 0, -159, 0, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, -159, -159, 0, -159, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -159, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 414 -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 0, -184, 0, -184, -184, -184, -184, -184, 0, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 0, 0, 0, -184, -184, -184, -184, -184, -184, 0, -184, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, 0, -184, -184, 0, -184, 0, -184, -184, 0, 0, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 415 - -427, -427, 0, 0, -427, 0, -427, 0, -427, 0, 0, -427, -427, 0, -427, 32, 0, -427, 0, 0, 0, 0, 0, -427, -427, -427, 0, -427, 0, 0, -427, 0, -427, 0, 0, 0, 0, -427, 0, 0, -427, 0, 0, 0, 0, 0, 0, -427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -427, -427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -427, -427, 0, 0, -427, 0, -427, 0, -427, 0, 0, -427, -427, 0, -427, 33, 0, -427, 0, 0, 0, 0, 0, -427, -427, -427, 0, -427, 0, 0, -427, 0, -427, 0, 0, 0, 0, -427, 0, 0, -427, 0, 0, 0, 0, 0, 0, -427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -427, -427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 416 - -865, -865, 0, 0, -865, 0, -865, 0, -865, 0, 0, -865, -865, 0, -865, -865, 0, -865, 0, 0, 0, 0, 0, -865, -865, -865, 0, -865, 0, 0, -865, 0, -865, 0, 0, 0, 0, -865, 0, 0, -865, 0, 0, 0, 0, -865, 0, -865, 0, -865, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, -865, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -864, -864, 0, 0, -864, 0, -864, 0, -864, 0, 0, -864, -864, 0, -864, -864, 0, -864, 0, 0, 0, 0, 0, -864, -864, -864, 0, -864, 0, 0, -864, 0, -864, 0, 0, 0, 0, -864, 0, 0, -864, 0, 0, 0, 0, -864, 0, -864, 0, -864, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, -864, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 417 -388, -388, -388, -388, -388, -388, -388, 0, -388, -388, 0, -388, -388, -388, -388, -388, -388, -388, 0, 0, 0, -388, -388, -388, -388, -388, 0, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, -388, 0, 0, 0, 0, -388, -388, -388, -388, -388, 0, -388, 0, 0, 0, 0, 0, 0, 0, 0, -388, 0, 0, -388, -388, 0, -388, 0, -388, -388, 0, 0, 0, -388, -388, 0, 0, 0, 0, 0, 0, 0, 0, 0, -388, -388, -388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 418 - -878, -878, 0, 0, -878, 0, -878, 0, -878, 0, 0, -878, -878, 0, -878, -878, 0, -878, 0, 0, 0, 0, 0, -878, -878, -878, 0, -878, 0, 0, -878, 0, -878, 0, 0, 0, 0, -878, 0, 0, -878, 0, 0, 0, 0, 0, 0, -878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -878, -878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -877, -877, 0, 0, -877, 0, -877, 0, -877, 0, 0, -877, -877, 0, -877, -877, 0, -877, 0, 0, 0, 0, 0, -877, -877, -877, 0, -877, 0, 0, -877, 0, -877, 0, 0, 0, 0, -877, 0, 0, -877, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -877, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 419 - -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, 0, -838, 0, -838, -838, -838, -838, -838, 0, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, 0, 0, 0, -838, -838, -838, -838, -838, -838, 0, -838, 0, 0, 0, 0, 0, 0, 0, 0, -838, 0, 0, -838, -838, 0, -838, 0, -838, -838, 0, 0, 0, -838, -838, 0, 0, 0, 0, 0, 0, 0, 0, 0, -838, -838, -838, 0, 0, 0, -838, 0, 0, 0, 0, 0, 0, 0, 0, 0, -838, + -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 0, -183, 0, -183, -183, -183, -183, -183, 0, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 0, 0, 0, -183, -183, -183, -183, -183, -183, 0, -183, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, 0, -183, -183, 0, -183, 0, -183, -183, 0, 0, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 420 - -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, 0, -840, 0, -840, -840, -840, -840, -840, 0, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, 0, 0, 0, -840, -840, -840, -840, -840, -840, 0, -840, 0, 0, 0, 0, 0, 0, 0, 0, -840, 0, 0, -840, -840, 0, -840, 0, -840, -840, 0, 0, 0, -840, -840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -840, -840, -840, 0, 0, 0, -840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -840, + -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, 0, -839, 0, -839, -839, -839, -839, -839, 0, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, 0, 0, 0, -839, -839, -839, -839, -839, -839, 0, -839, 0, 0, 0, 0, 0, 0, 0, 0, -839, 0, 0, -839, -839, 0, -839, 0, -839, -839, 0, 0, 0, -839, -839, 0, 0, 0, 0, 0, 0, 0, 0, 0, -839, -839, -839, 0, 0, 0, -839, 0, 0, 0, 0, 0, 0, 0, 0, 0, -839, // State 421 - -877, -877, 0, 0, -877, 0, -877, 0, -877, 0, 0, -877, -877, 0, -877, -877, 0, -877, 0, 0, 0, 0, 0, -877, -877, -877, 0, -877, 0, 0, -877, 0, -877, 0, 0, 0, 0, -877, 0, 0, -877, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -877, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -876, -876, 0, 0, -876, 0, -876, 0, -876, 0, 0, -876, -876, 0, -876, -876, 0, -876, 0, 0, 0, 0, 0, -876, -876, -876, 0, -876, 0, 0, -876, 0, -876, 0, 0, 0, 0, -876, 0, 0, -876, 0, 0, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -876, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 422 - -550, -550, 0, 0, -550, 0, -550, 0, -550, 0, 0, -550, -550, 0, -550, -550, 0, -550, 0, 0, 0, 0, 0, -550, -550, -550, 0, -550, 0, 0, -550, 0, -550, 0, 0, 0, 0, -550, 0, 0, -550, 0, 0, 0, 0, 0, 0, -550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -550, -550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -551, -551, 0, 0, -551, 0, -551, 0, -551, 0, 0, -551, -551, 0, -551, -551, 0, -551, 0, 0, 0, 0, 0, -551, -551, -551, 0, -551, 0, 0, -551, 0, -551, 0, 0, 0, 0, -551, 0, 0, -551, 0, 0, 0, 0, 0, 0, -551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -551, -551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 423 - -349, -349, -349, 0, -349, 0, -349, 0, -349, 0, 0, -349, -349, 0, -349, -349, 0, -349, 0, 0, 0, 0, 0, -349, -349, -349, 0, -349, -349, 0, -349, -349, -349, -349, -349, -349, 0, -349, -349, 0, -349, 0, 0, 0, 0, -349, 36, -349, -349, -349, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, 0, -349, -349, 0, -349, 0, -349, -349, 0, 0, 0, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -349, -349, -349, 0, -349, 0, -349, 0, -349, 0, 0, -349, -349, 0, -349, -349, 0, -349, 0, 0, 0, 0, 0, -349, -349, -349, 0, -349, -349, 0, -349, -349, -349, -349, -349, -349, 0, -349, -349, 0, -349, 0, 0, 0, 0, -349, 37, -349, -349, -349, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, 0, -349, -349, 0, -349, 0, -349, -349, 0, 0, 0, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 424 - 0, 0, 0, 0, 0, 0, 0, -915, 0, 0, 0, 0, 0, -915, 0, 0, -915, 0, 0, 0, -915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -915, -915, -915, -915, 0, 0, 0, 0, 0, 0, 0, -915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -915, 0, 0, 0, -915, 0, 0, -915, 0, 0, 0, -915, -915, 0, -915, 0, -915, -915, + 0, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, 0, 0, -918, 0, 0, -918, 0, 0, 0, -918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -918, -918, -918, -918, 0, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, -918, 0, 0, -918, 0, 0, 0, -918, -918, 0, -918, 0, -918, -918, // State 425 - 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, -916, 0, 0, -916, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -916, -916, -916, -916, 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, -916, 0, 0, -916, 0, 0, 0, -916, -916, 0, -916, 0, -916, -916, + 0, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, 0, 0, -919, 0, 0, -919, 0, 0, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -919, -919, -919, -919, 0, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, -919, 0, 0, -919, 0, 0, 0, -919, -919, 0, -919, 0, -919, -919, // State 426 -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 0, -211, 0, -211, -211, -211, -211, -211, 0, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 0, 0, 0, -211, -211, -211, -211, -211, -211, 0, -211, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, 0, -211, -211, 0, -211, 0, -211, -211, 0, 0, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 427 @@ -1012,21 +1015,21 @@ mod __parse__Top { // State 429 -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 0, -208, 0, -208, -208, -208, -208, -208, 0, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 0, 0, 0, -208, -208, -208, -208, -208, -208, 0, -208, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, 0, -208, -208, 0, -208, 0, -208, -208, 0, 0, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 430 - 0, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, 0, 0, -917, 0, 0, -917, 0, 0, 0, -917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -917, -917, -917, -917, 0, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, -917, 0, 0, -917, 0, 0, 0, -917, -917, 0, -917, 0, -917, -917, + 0, 0, 0, 0, 0, 0, 0, -920, 0, 0, 0, 0, 0, -920, 0, 0, -920, 0, 0, 0, -920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -920, -920, -920, -920, 0, 0, 0, 0, 0, 0, 0, -920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -920, 0, 0, 0, -920, 0, 0, -920, 0, 0, 0, -920, -920, 0, -920, 0, -920, -920, // State 431 - -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, 0, -520, 0, -520, -520, -520, -520, -520, 0, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, 0, 0, 0, -520, -520, -520, -520, -520, -520, 0, -520, 0, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, -520, -520, 0, -520, 0, -520, -520, 0, 0, 0, -520, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, -520, -520, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, 0, -521, 0, -521, -521, -521, -521, -521, 0, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, -521, 0, 0, 0, -521, -521, -521, -521, -521, -521, 0, -521, 0, 0, 0, 0, 0, 0, 0, 0, -521, 0, 0, -521, -521, 0, -521, 0, -521, -521, 0, 0, 0, -521, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, -521, -521, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 432 - -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, 0, -519, 0, -519, -519, -519, -519, -519, 0, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, 0, 0, 0, -519, -519, -519, -519, -519, -519, 0, -519, 0, 0, 0, 0, 0, 0, 0, 0, -519, 0, 0, -519, -519, 0, -519, 0, -519, -519, 0, 0, 0, -519, -519, 0, 0, 0, 0, 0, 0, 0, 0, 0, -519, -519, -519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, 0, -520, 0, -520, -520, -520, -520, -520, 0, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, -520, 0, 0, 0, -520, -520, -520, -520, -520, -520, 0, -520, 0, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, -520, -520, 0, -520, 0, -520, -520, 0, 0, 0, -520, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, -520, -520, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 433 - -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, 0, -518, 0, -518, -518, -518, -518, -518, 0, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, -518, 0, 0, 0, -518, -518, -518, -518, -518, -518, 0, -518, 0, 0, 0, 0, 0, 0, 0, 0, -518, 0, 0, -518, -518, 0, -518, 0, -518, -518, 0, 0, 0, -518, -518, 0, 0, 0, 0, 0, 0, 0, 0, 0, -518, -518, -518, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, 0, -519, 0, -519, -519, -519, -519, -519, 0, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, -519, 0, 0, 0, -519, -519, -519, -519, -519, -519, 0, -519, 0, 0, 0, 0, 0, 0, 0, 0, -519, 0, 0, -519, -519, 0, -519, 0, -519, -519, 0, 0, 0, -519, -519, 0, 0, 0, 0, 0, 0, 0, 0, 0, -519, -519, -519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 434 -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 0, -430, 0, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, -430, 0, 0, 0, -430, -430, -430, -430, -430, -430, 0, -430, 0, 0, 0, 0, 0, 0, 0, 0, -430, 0, 0, -430, -430, 0, -430, -430, -430, -430, 0, 0, 0, -430, -430, 0, 0, 0, 0, 0, 0, 0, 0, 0, -430, -430, -430, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 435 - -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, 0, -835, 0, -835, -835, -835, -835, -835, 0, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, 0, 0, 0, -835, -835, -835, -835, -835, -835, 0, -835, 0, 0, 0, 0, 0, 0, 0, 0, -835, 0, 0, -835, -835, 0, -835, 0, -835, -835, 0, 0, 0, -835, -835, 0, 0, 0, 0, 0, 0, 0, 0, 0, -835, -835, -835, 0, 0, 0, -835, 0, 0, 0, 0, 0, 0, 0, 0, 0, -835, + -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, 0, -838, 0, -838, -838, -838, -838, -838, 0, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, 0, 0, 0, -838, -838, -838, -838, -838, -838, 0, -838, 0, 0, 0, 0, 0, 0, 0, 0, -838, 0, 0, -838, -838, 0, -838, 0, -838, -838, 0, 0, 0, -838, -838, 0, 0, 0, 0, 0, 0, 0, 0, 0, -838, -838, -838, 0, 0, 0, -838, 0, 0, 0, 0, 0, 0, 0, 0, 0, -838, // State 436 - -558, -558, 0, 0, -558, 0, -558, 0, -558, 0, 0, -558, -558, 0, -558, -558, 0, -558, 0, 0, 0, 0, 0, -558, -558, -558, 0, -558, 0, 0, -558, 0, -558, 0, 0, 0, 0, -558, 0, 0, -558, 0, 0, 0, 0, -558, 0, -558, 0, -558, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, -558, -558, 0, -558, 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -559, -559, 0, 0, -559, 0, -559, 0, -559, 0, 0, -559, -559, 0, -559, -559, 0, -559, 0, 0, 0, 0, 0, -559, -559, -559, 0, -559, 0, 0, -559, 0, -559, 0, 0, 0, 0, -559, 0, 0, -559, 0, 0, 0, 0, -559, 0, -559, 0, -559, 0, -559, 0, 0, 0, 0, 0, 0, 0, 0, -559, 0, 0, -559, -559, 0, -559, 0, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -559, -559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 437 - -158, -158, 0, 0, -158, 0, -158, 0, -158, 0, 0, -158, -158, 0, -158, -158, 0, -158, 0, 0, 0, 0, 0, -158, -158, -158, 0, -158, 0, 0, -158, 0, -158, 0, 0, 0, 0, -158, 0, 0, -158, 0, 0, 0, 0, -158, 0, -158, 532, -158, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, -158, -158, 0, -158, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -158, -158, 0, 0, -158, 0, -158, 0, -158, 0, 0, -158, -158, 0, -158, -158, 0, -158, 0, 0, 0, 0, 0, -158, -158, -158, 0, -158, 0, 0, -158, 0, -158, 0, 0, 0, 0, -158, 0, 0, -158, 0, 0, 0, 0, -158, 0, -158, 533, -158, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, -158, -158, 0, -158, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 438 0, 0, 0, 0, 0, 0, 0, -113, 0, 0, 0, 0, 0, -113, 0, 0, -113, 0, 0, 0, -113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, -113, -113, -113, 0, 0, 0, 0, 0, 0, 0, -113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, 0, 0, 0, -113, 0, 0, -113, 0, 0, 0, -113, -113, 0, -113, 0, -113, -113, // State 439 @@ -1050,1481 +1053,1487 @@ mod __parse__Top { // State 448 0, 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, 0, 0, -299, 0, 0, -299, 0, 0, 0, -299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -299, -299, -299, -299, 0, 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, -299, 0, 0, -299, 0, 0, 0, -299, -299, 0, -299, 0, -299, -299, // State 449 - 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, 0, 0, -301, 0, 0, -301, 0, 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, -301, -301, -301, 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, -301, 0, 0, -301, 0, 0, 0, -301, -301, 0, -301, 0, -301, -301, + 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, 0, 0, -301, 0, 0, -301, 0, 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, -301, -301, -301, 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, -301, 0, 0, -301, 0, 0, 0, -301, -301, 0, -301, 0, -301, -301, // State 450 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 451 - 547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 452 -90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 453 0, 0, 0, 0, 0, 0, 0, -121, 0, 0, 0, 0, 0, -121, 0, 0, -121, 0, 0, 0, -121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -121, -121, -121, -121, 0, 0, 0, 0, 0, 0, 0, -121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -121, 0, 0, 0, 0, 0, 0, 0, 0, 0, -121, 0, 0, 0, -121, 0, 0, -121, 0, 0, 0, -121, -121, 0, -121, 0, -121, -121, // State 454 - 0, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, 0, 0, -793, 0, 0, -793, 0, 0, 0, -793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -793, -793, -793, -793, 0, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, -793, 0, 0, -793, 0, 0, 0, -793, -793, 0, -793, 0, -793, -793, - // State 455 0, 0, 0, 0, 0, 0, 0, -794, 0, 0, 0, 0, 0, -794, 0, 0, -794, 0, 0, 0, -794, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -794, -794, -794, -794, 0, 0, 0, 0, 0, 0, 0, -794, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -794, 0, 0, 0, -794, 0, 0, -794, 0, 0, 0, -794, -794, 0, -794, 0, -794, -794, + // State 455 + 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, -795, 0, 0, -795, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -795, -795, -795, -795, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, -795, 0, 0, -795, 0, 0, 0, -795, -795, 0, -795, 0, -795, -795, // State 456 - -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, 0, -841, 0, -841, -841, -841, -841, -841, 0, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, 0, 0, 0, -841, -841, -841, -841, -841, -841, 0, -841, 0, 0, 0, 0, 0, 0, 0, 0, -841, 0, 0, -841, -841, 0, -841, 0, -841, -841, 0, 0, 0, -841, -841, 0, 0, 0, 0, 0, 0, 0, 0, 0, -841, -841, -841, 0, 0, 0, -841, 0, 0, 0, 0, 0, 0, 0, 0, 0, -841, + -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, 0, -895, 0, -895, -895, -895, -895, -895, 0, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, -895, 0, 0, 0, -895, -895, -895, -895, -895, -895, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, -895, -895, 0, -895, 0, -895, -895, 0, 0, 0, -895, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, -895, -895, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, // State 457 - 0, 0, 0, 0, 0, 0, 0, -505, 0, 0, 0, 0, 0, -505, 0, 0, -505, 0, 0, 0, -505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505, -505, -505, -505, 0, 0, 0, 0, 0, 0, 0, -505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505, 0, 0, 0, -505, 0, 0, -505, 0, 0, 0, -505, -505, 0, -505, 0, -505, -505, + 0, 0, 0, 0, 0, 0, 0, -506, 0, 0, 0, 0, 0, -506, 0, 0, -506, 0, 0, 0, -506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506, -506, -506, -506, 0, 0, 0, 0, 0, 0, 0, -506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506, 0, 0, 0, -506, 0, 0, -506, 0, 0, 0, -506, -506, 0, -506, 0, -506, -506, // State 458 - 0, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, 0, 0, -502, 0, 0, -502, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, -502, -502, -502, 0, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, -502, 0, 0, -502, 0, 0, 0, -502, -502, 0, -502, 0, -502, -502, - // State 459 0, 0, 0, 0, 0, 0, 0, -503, 0, 0, 0, 0, 0, -503, 0, 0, -503, 0, 0, 0, -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -503, -503, -503, -503, 0, 0, 0, 0, 0, 0, 0, -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -503, 0, 0, 0, -503, 0, 0, -503, 0, 0, 0, -503, -503, 0, -503, 0, -503, -503, - // State 460 + // State 459 0, 0, 0, 0, 0, 0, 0, -504, 0, 0, 0, 0, 0, -504, 0, 0, -504, 0, 0, 0, -504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504, -504, -504, -504, 0, 0, 0, 0, 0, 0, 0, -504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504, 0, 0, 0, -504, 0, 0, -504, 0, 0, 0, -504, -504, 0, -504, 0, -504, -504, + // State 460 + 0, 0, 0, 0, 0, 0, 0, -505, 0, 0, 0, 0, 0, -505, 0, 0, -505, 0, 0, 0, -505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505, -505, -505, -505, 0, 0, 0, 0, 0, 0, 0, -505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505, 0, 0, 0, -505, 0, 0, -505, 0, 0, 0, -505, -505, 0, -505, 0, -505, -505, // State 461 - 0, 0, 0, 0, 0, 0, 0, -506, 0, 0, 0, 0, 0, -506, 0, 0, -506, 0, 0, 0, -506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506, -506, -506, -506, 0, 0, 0, 0, 0, 0, 0, -506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506, 0, 0, 0, -506, 0, 0, -506, 0, 0, 0, -506, -506, 0, -506, 0, -506, -506, + 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, -507, 0, 0, -507, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, -507, -507, -507, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, -507, 0, 0, -507, 0, 0, 0, -507, -507, 0, -507, 0, -507, -507, // State 462 - -387, -387, -387, -387, -387, -387, -387, 0, -387, -387, 0, -387, -387, -387, -387, -387, -387, -387, 0, 0, 0, -387, -387, -387, -387, -387, 0, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, 0, 0, 0, 0, -387, -387, -387, -387, -387, 0, -387, 0, 0, 0, 0, 0, 0, 0, 0, -387, 0, 0, -387, -387, 0, -387, 0, -387, -387, 0, 0, 0, -387, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, -387, -387, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, 0, -896, 0, -896, -896, -896, -896, -896, 0, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, -896, 0, 0, 0, -896, -896, -896, -896, -896, -896, 0, -896, 0, 0, 0, 0, 0, 0, 0, 0, -896, 0, 0, -896, -896, 0, -896, 0, -896, -896, 0, 0, 0, -896, -896, 0, 0, 0, 0, 0, 0, 0, 0, 0, -896, -896, -896, 0, 0, 0, -896, 0, 0, 0, 0, 0, 0, 0, 0, 0, -896, // State 463 - -185, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, -508, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, -185, -185, 0, -185, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -387, -387, -387, -387, -387, -387, -387, 0, -387, -387, 0, -387, -387, -387, -387, -387, -387, -387, 0, 0, 0, -387, -387, -387, -387, -387, 0, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, -387, 0, 0, 0, 0, -387, -387, -387, -387, -387, 0, -387, 0, 0, 0, 0, 0, 0, 0, 0, -387, 0, 0, -387, -387, 0, -387, 0, -387, -387, 0, 0, 0, -387, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, -387, -387, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 464 - 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -185, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, -509, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, -185, -185, 0, -185, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 465 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 466 - 0, 0, 0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 467 - 0, 0, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 468 - 0, 0, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 469 - 0, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 470 - -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 0, -199, 0, -199, -199, -199, -199, -199, 0, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 0, 0, 0, -199, -199, -199, -199, -199, -199, 0, -199, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, 0, -199, -199, 0, -199, 0, -199, -199, 0, 0, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 471 - -816, -816, 0, 0, -816, 0, -816, 0, -816, 0, 0, -816, -816, 0, -816, -816, 0, -816, 0, 0, 0, 0, 0, -816, -816, -816, 0, -816, 0, 0, -816, 0, -816, 0, 0, 0, 0, -816, 0, 0, -816, 0, 0, 0, 0, -816, 0, -816, 0, 0, 0, -816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -816, 0, 0, 0, 0, -816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -816, -816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 0, -199, 0, -199, -199, -199, -199, -199, 0, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 0, 0, 0, -199, -199, -199, -199, -199, -199, 0, -199, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, 0, -199, -199, 0, -199, 0, -199, -199, 0, 0, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 472 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -817, -817, 0, 0, -817, 0, -817, 0, -817, 0, 0, -817, -817, 0, -817, -817, 0, -817, 0, 0, 0, 0, 0, -817, -817, -817, 0, -817, 0, 0, -817, 0, -817, 0, 0, 0, 0, -817, 0, 0, -817, 0, 0, 0, 0, -817, 0, -817, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, -817, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 473 - -509, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 474 - 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -510, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 475 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 476 - 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 477 - -510, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 478 - -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 0, -187, 0, -187, -187, -187, -187, -187, 0, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 0, 0, 0, -187, -187, -187, -187, -187, -187, 0, -187, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, 0, -187, -187, 0, -187, 0, -187, -187, 0, 0, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -511, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 479 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 0, -187, 0, -187, -187, -187, -187, -187, 0, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 0, 0, 0, -187, -187, -187, -187, -187, -187, 0, -187, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, 0, -187, -187, 0, -187, 0, -187, -187, 0, 0, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 480 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 0, 0, 0, -727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -921, 0, 0, 0, 0, 0, 0, 0, 0, 0, -921, 0, 0, 0, 0, 0, 0, -921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 481 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, -701, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 564, 0, 0, 0, 0, 0, 0, 0, 0, 0, -728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 482 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -544, 0, 0, 0, 0, 0, 0, 0, 0, 0, -544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, -702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 483 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -545, 0, 0, 0, 0, 0, 0, 0, 0, 0, -545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 484 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -564, 0, 0, 0, 0, 0, 0, 0, 0, 0, -564, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 485 - -514, -514, 0, 0, -514, 0, -514, 0, -514, 0, 0, -514, -514, 0, -514, -514, 0, -514, 0, 0, 0, 0, 0, -514, -514, -514, 0, -514, 0, 0, -514, 0, -514, 0, 0, 0, 0, -514, 0, 0, -514, 0, 0, 0, 0, -514, 0, -514, -514, -514, 0, -514, 0, 0, 0, 0, 0, 0, 0, 0, -514, 0, 0, -514, -514, 0, -514, 0, 0, 0, 0, 0, 0, 0, -514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -514, -514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -565, 0, 0, 0, 0, 0, 0, 0, 0, 0, -565, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 486 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -515, -515, 0, 0, -515, 0, -515, 0, -515, 0, 0, -515, -515, 0, -515, -515, 0, -515, 0, 0, 0, 0, 0, -515, -515, -515, 0, -515, 0, 0, -515, 0, -515, 0, 0, 0, 0, -515, 0, 0, -515, 0, 0, 0, 0, -515, 0, -515, -515, -515, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, -515, -515, 0, -515, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 487 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 488 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 570, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 489 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 490 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 491 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 492 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 493 - -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 0, -204, 0, -204, -204, -204, -204, -204, 0, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 0, 0, 0, -204, -204, -204, -204, -204, -204, 0, -204, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, 0, -204, -204, 0, -204, 0, -204, -204, 0, 0, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 494 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -377, 0, 0, -377, 0, 0, -377, 0, 0, 0, 0, 0, 0, -377, 0, 0, 0, 0, + -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 0, -204, 0, -204, -204, -204, -204, -204, 0, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 0, 0, 0, -204, -204, -204, -204, -204, -204, 0, -204, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, 0, -204, -204, 0, -204, 0, -204, -204, 0, 0, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 495 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -373, 0, 0, -373, 0, 0, -373, 0, 0, 0, 0, 0, 0, -373, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -377, 0, 0, -377, 0, 0, -377, 0, 0, 0, 0, 0, 0, -377, 0, 0, 0, 0, // State 496 - -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 0, -366, 0, -366, -366, -366, -366, -366, 0, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 0, 0, 0, -366, -366, -366, -366, -366, -366, 0, -366, 0, 0, 0, 0, 0, 0, 0, 0, -366, 0, 0, -366, -366, 0, -366, 0, -366, -366, 0, 0, 0, -366, -366, 0, 0, 0, 0, 0, 0, 0, 0, 0, -366, -366, -366, 0, 0, 0, -366, 0, 0, 0, 0, 0, 0, 0, 0, 0, -366, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -373, 0, 0, -373, 0, 0, -373, 0, 0, 0, 0, 0, 0, -373, 0, 0, 0, 0, // State 497 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -374, 0, 0, -374, 0, 0, -374, 0, 0, 0, 0, 0, 0, -374, 0, 0, 0, 0, + -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 0, -366, 0, -366, -366, -366, -366, -366, 0, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, 0, 0, 0, -366, -366, -366, -366, -366, -366, 0, -366, 0, 0, 0, 0, 0, 0, 0, 0, -366, 0, 0, -366, -366, 0, -366, 0, -366, -366, 0, 0, 0, -366, -366, 0, 0, 0, 0, 0, 0, 0, 0, 0, -366, -366, -366, 0, 0, 0, -366, 0, 0, 0, 0, 0, 0, 0, 0, 0, -366, // State 498 - -812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -374, 0, 0, -374, 0, 0, -374, 0, 0, 0, 0, 0, 0, -374, 0, 0, 0, 0, // State 499 - -314, 0, 0, 0, 0, 0, 0, -314, 0, -314, 0, 0, 0, -314, 0, 0, -314, 0, 0, 0, -314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -314, 0, -314, -314, -314, -314, 0, 0, 0, 0, 0, -314, -314, -314, -314, 0, -314, -314, -314, -314, 0, 0, 0, 0, -314, -314, -314, -314, -314, 0, 0, -314, -314, -314, -314, 0, -314, -314, -314, -314, -314, -314, -314, -314, -314, 0, 0, 0, -314, -314, 0, -314, 0, 0, 0, -314, -314, 0, -314, -314, -314, -314, + -813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 500 - -769, 0, 0, 0, 0, 0, 0, -769, 0, -769, 0, 0, 0, -769, 0, 0, -769, 0, 0, 0, -769, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -769, 0, -769, -769, -769, -769, 0, 0, 0, 0, 0, -769, -769, -769, -769, 0, -769, -769, -769, -769, 0, 0, 0, 0, -769, -769, -769, -769, -769, 0, 0, -769, -769, -769, -769, 0, -769, -769, -769, -769, -769, -769, -769, -769, -769, 0, 0, 0, -769, 0, 0, -769, 0, 0, 0, -769, -769, 0, -769, -769, -769, -769, + -314, 0, 0, 0, 0, 0, 0, -314, 0, -314, 0, 0, 0, -314, 0, 0, -314, 0, 0, 0, -314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -314, 0, -314, -314, -314, -314, 0, 0, 0, 0, 0, -314, -314, -314, -314, 0, -314, -314, -314, -314, 0, 0, 0, 0, -314, -314, -314, -314, -314, 0, 0, -314, -314, -314, -314, 0, -314, -314, -314, -314, -314, -314, -314, -314, -314, 0, 0, 0, -314, -314, 0, -314, 0, 0, 0, -314, -314, 0, -314, -314, -314, -314, // State 501 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, 0, -323, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -770, 0, 0, 0, 0, 0, 0, -770, 0, -770, 0, 0, 0, -770, 0, 0, -770, 0, 0, 0, -770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -770, 0, -770, -770, -770, -770, 0, 0, 0, 0, 0, -770, -770, -770, -770, 0, -770, -770, -770, -770, 0, 0, 0, 0, -770, -770, -770, -770, -770, 0, 0, -770, -770, -770, -770, 0, -770, -770, -770, -770, -770, -770, -770, -770, -770, 0, 0, 0, -770, 0, 0, -770, 0, 0, 0, -770, -770, 0, -770, -770, -770, -770, // State 502 - -807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, 0, -323, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 503 - -805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 504 -808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 504 + -806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 505 - -310, 0, 0, 0, 0, 0, 0, -310, 0, -310, 0, 0, 0, -310, 0, 0, -310, 0, 0, 0, -310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -310, 0, -310, -310, -310, -310, 0, 0, 0, 0, 0, -310, -310, -310, -310, 0, -310, -310, -310, -310, 0, 0, 0, 0, -310, -310, -310, -310, -310, 0, 0, -310, -310, -310, -310, 0, -310, -310, -310, -310, -310, -310, -310, -310, -310, 0, 0, 0, -310, -310, 0, -310, 0, 0, 0, -310, -310, 0, -310, -310, -310, -310, + -809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 506 - -313, 0, 0, 0, 0, 0, 0, -313, 0, -313, 0, 0, 0, -313, 0, 0, -313, 0, 0, 0, -313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -313, 0, -313, -313, -313, -313, 0, 0, 0, 0, 0, -313, -313, -313, -313, 0, -313, -313, -313, -313, 0, 0, 0, 0, -313, -313, -313, -313, -313, 0, 0, -313, -313, -313, -313, 0, -313, -313, -313, -313, -313, -313, -313, -313, -313, 0, 0, 0, -313, -313, 0, -313, 0, 0, 0, -313, -313, 0, -313, -313, -313, -313, + -310, 0, 0, 0, 0, 0, 0, -310, 0, -310, 0, 0, 0, -310, 0, 0, -310, 0, 0, 0, -310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -310, 0, -310, -310, -310, -310, 0, 0, 0, 0, 0, -310, -310, -310, -310, 0, -310, -310, -310, -310, 0, 0, 0, 0, -310, -310, -310, -310, -310, 0, 0, -310, -310, -310, -310, 0, -310, -310, -310, -310, -310, -310, -310, -310, -310, 0, 0, 0, -310, -310, 0, -310, 0, 0, 0, -310, -310, 0, -310, -310, -310, -310, // State 507 - -810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -313, 0, 0, 0, 0, 0, 0, -313, 0, -313, 0, 0, 0, -313, 0, 0, -313, 0, 0, 0, -313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -313, 0, -313, -313, -313, -313, 0, 0, 0, 0, 0, -313, -313, -313, -313, 0, -313, -313, -313, -313, 0, 0, 0, 0, -313, -313, -313, -313, -313, 0, 0, -313, -313, -313, -313, 0, -313, -313, -313, -313, -313, -313, -313, -313, -313, 0, 0, 0, -313, -313, 0, -313, 0, 0, 0, -313, -313, 0, -313, -313, -313, -313, // State 508 - -308, 0, 0, 0, 0, 0, 0, -308, 0, -308, 0, 0, 0, -308, 0, 0, -308, 0, 0, 0, -308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -308, 0, -308, -308, -308, -308, 0, 0, 0, 0, 0, -308, -308, -308, -308, 0, -308, -308, -308, -308, 0, 0, 0, 0, -308, -308, -308, -308, -308, 0, 0, -308, -308, -308, -308, 0, -308, -308, -308, -308, -308, -308, -308, -308, -308, 0, 0, 0, -308, -308, 0, -308, 0, 0, 0, -308, -308, 0, -308, -308, -308, -308, + -811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 509 - -809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -308, 0, 0, 0, 0, 0, 0, -308, 0, -308, 0, 0, 0, -308, 0, 0, -308, 0, 0, 0, -308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -308, 0, -308, -308, -308, -308, 0, 0, 0, 0, 0, -308, -308, -308, -308, 0, -308, -308, -308, -308, 0, 0, 0, 0, -308, -308, -308, -308, -308, 0, 0, -308, -308, -308, -308, 0, -308, -308, -308, -308, -308, -308, -308, -308, -308, 0, 0, 0, -308, -308, 0, -308, 0, 0, 0, -308, -308, 0, -308, -308, -308, -308, // State 510 - -814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 511 -815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 512 - -307, 0, 0, 0, 0, 0, 0, -307, 0, -307, 0, 0, 0, -307, 0, 0, -307, 0, 0, 0, -307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -307, 0, -307, -307, -307, -307, 0, 0, 0, 0, 0, -307, -307, -307, -307, 0, -307, -307, -307, -307, 0, 0, 0, 0, -307, -307, -307, -307, -307, 0, 0, -307, -307, -307, -307, 0, -307, -307, -307, -307, -307, -307, -307, -307, -307, 0, 0, 0, -307, -307, 0, -307, 0, 0, 0, -307, -307, 0, -307, -307, -307, -307, + -816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 513 - -811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -307, 0, 0, 0, 0, 0, 0, -307, 0, -307, 0, 0, 0, -307, 0, 0, -307, 0, 0, 0, -307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -307, 0, -307, -307, -307, -307, 0, 0, 0, 0, 0, -307, -307, -307, -307, 0, -307, -307, -307, -307, 0, 0, 0, 0, -307, -307, -307, -307, -307, 0, 0, -307, -307, -307, -307, 0, -307, -307, -307, -307, -307, -307, -307, -307, -307, 0, 0, 0, -307, -307, 0, -307, 0, 0, 0, -307, -307, 0, -307, -307, -307, -307, // State 514 - -806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 515 - -396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 516 - 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 517 - -877, 0, 0, 0, -877, 0, -877, 0, 0, 0, 0, -877, -877, 0, -877, -877, 0, -877, 0, 0, 0, 0, 0, -877, -877, 103, 0, -877, 0, 0, -877, 0, -877, 0, 0, 0, 0, -877, 0, 0, -877, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 518 - -311, 0, 0, 0, 0, 0, 0, -311, 0, -311, 0, 0, 0, -311, 0, 0, -311, 0, 0, 0, -311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -311, 0, -311, -311, -311, -311, 0, 0, 0, 0, 0, -311, -311, -311, -311, 0, -311, -311, -311, -311, 0, 0, 0, 0, -311, -311, -311, -311, -311, 0, 0, -311, -311, -311, -311, 0, -311, -311, -311, -311, -311, -311, -311, -311, -311, 0, 0, 0, -311, -311, 0, -311, 0, 0, 0, -311, -311, 0, -311, -311, -311, -311, + -876, 0, 0, 0, -876, 0, -876, 0, 0, 0, 0, -876, -876, 0, -876, -876, 0, -876, 0, 0, 0, 0, 0, -876, -876, 104, 0, -876, 0, 0, -876, 0, -876, 0, 0, 0, 0, -876, 0, 0, -876, 0, 0, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 519 - -813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -311, 0, 0, 0, 0, 0, 0, -311, 0, -311, 0, 0, 0, -311, 0, 0, -311, 0, 0, 0, -311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -311, 0, -311, -311, -311, -311, 0, 0, 0, 0, 0, -311, -311, -311, -311, 0, -311, -311, -311, -311, 0, 0, 0, 0, -311, -311, -311, -311, -311, 0, 0, -311, -311, -311, -311, 0, -311, -311, -311, -311, -311, -311, -311, -311, -311, 0, 0, 0, -311, -311, 0, -311, 0, 0, 0, -311, -311, 0, -311, -311, -311, -311, // State 520 - -309, 0, 0, 0, 0, 0, 0, -309, 0, -309, 0, 0, 0, -309, 0, 0, -309, 0, 0, 0, -309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -309, 0, -309, -309, -309, -309, 0, 0, 0, 0, 0, -309, -309, -309, -309, 0, -309, -309, -309, -309, 0, 0, 0, 0, -309, -309, -309, -309, -309, 0, 0, -309, -309, -309, -309, 0, -309, -309, -309, -309, -309, -309, -309, -309, -309, 0, 0, 0, -309, -309, 0, -309, 0, 0, 0, -309, -309, 0, -309, -309, -309, -309, + -814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 521 - -312, 0, 0, 0, 0, 0, 0, -312, 0, -312, 0, 0, 0, -312, 0, 0, -312, 0, 0, 0, -312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -312, 0, -312, -312, -312, -312, 0, 0, 0, 0, 0, -312, -312, -312, -312, 0, -312, -312, -312, -312, 0, 0, 0, 0, -312, -312, -312, -312, -312, 0, 0, -312, -312, -312, -312, 0, -312, -312, -312, -312, -312, -312, -312, -312, -312, 0, 0, 0, -312, -312, 0, -312, 0, 0, 0, -312, -312, 0, -312, -312, -312, -312, + -309, 0, 0, 0, 0, 0, 0, -309, 0, -309, 0, 0, 0, -309, 0, 0, -309, 0, 0, 0, -309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -309, 0, -309, -309, -309, -309, 0, 0, 0, 0, 0, -309, -309, -309, -309, 0, -309, -309, -309, -309, 0, 0, 0, 0, -309, -309, -309, -309, -309, 0, 0, -309, -309, -309, -309, 0, -309, -309, -309, -309, -309, -309, -309, -309, -309, 0, 0, 0, -309, -309, 0, -309, 0, 0, 0, -309, -309, 0, -309, -309, -309, -309, // State 522 - -395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -312, 0, 0, 0, 0, 0, 0, -312, 0, -312, 0, 0, 0, -312, 0, 0, -312, 0, 0, 0, -312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -312, 0, -312, -312, -312, -312, 0, 0, 0, 0, 0, -312, -312, -312, -312, 0, -312, -312, -312, -312, 0, 0, 0, 0, -312, -312, -312, -312, -312, 0, 0, -312, -312, -312, -312, 0, -312, -312, -312, -312, -312, -312, -312, -312, -312, 0, 0, 0, -312, -312, 0, -312, 0, 0, 0, -312, -312, 0, -312, -312, -312, -312, // State 523 - -774, 0, 0, 0, 0, 0, 0, -774, 0, -774, 0, 0, 0, -774, 0, 0, -774, 0, 0, 0, -774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -774, 0, -774, -774, -774, -774, 0, 0, 0, 0, 0, -774, -774, -774, -774, 0, -774, -774, -774, -774, 0, 0, 0, 0, -774, -774, -774, -774, -774, 0, 0, -774, -774, -774, -774, 0, -774, -774, -774, -774, -774, -774, -774, -774, -774, 0, 0, 0, -774, 0, 0, -774, 0, 0, 0, -774, -774, 0, -774, -774, -774, -774, + -395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 524 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -775, 0, 0, 0, 0, 0, 0, -775, 0, -775, 0, 0, 0, -775, 0, 0, -775, 0, 0, 0, -775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -775, 0, -775, -775, -775, -775, 0, 0, 0, 0, 0, -775, -775, -775, -775, 0, -775, -775, -775, -775, 0, 0, 0, 0, -775, -775, -775, -775, -775, 0, 0, -775, -775, -775, -775, 0, -775, -775, -775, -775, -775, -775, -775, -775, -775, 0, 0, 0, -775, 0, 0, -775, 0, 0, 0, -775, -775, 0, -775, -775, -775, -775, // State 525 - -391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 526 - -392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 527 - -748, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -748, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 528 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 529 - -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 530 - 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, -114, 0, 0, -114, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, -114, -114, -114, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, -114, 0, 0, -114, 0, 0, 0, -114, -114, 0, -114, 0, -114, -114, + -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 531 - 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, -122, 0, 0, -122, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, -122, -122, -122, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, -122, 0, 0, -122, 0, 0, 0, -122, -122, 0, -122, 0, -122, -122, + 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, -114, 0, 0, -114, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, -114, -114, -114, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, -114, 0, 0, -114, 0, 0, 0, -114, -114, 0, -114, 0, -114, -114, // State 532 - 0, 0, 0, 0, 0, 0, 0, 0, 658, 0, 0, 0, 0, 0, 0, 659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, -122, 0, 0, -122, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, -122, -122, -122, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, -122, 0, 0, -122, 0, 0, 0, -122, -122, 0, -122, 0, -122, -122, // State 533 - 0, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -508, 0, -185, -185, 0, -185, 128, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, 0, -185, 0, -185, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 660, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 534 - -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 0, -163, 0, -163, -163, -163, -163, -163, 0, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 0, 0, 0, -163, -163, -163, -163, -163, -163, 0, -163, 0, 0, 0, 0, 0, 0, 0, 0, -163, 0, 0, -163, -163, 0, -163, 0, -163, -163, 0, 0, 0, -163, -163, 0, 0, 0, 0, 0, 0, 0, 0, 0, -163, -163, -163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -509, 0, -185, -185, 0, -185, 128, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, 0, -185, 0, -185, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 535 - -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 0, -242, 0, -242, -242, -242, -242, -242, 0, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 0, 0, 0, -242, -242, -242, -242, -242, -242, 0, -242, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, 0, -242, -242, 0, -242, 0, -242, -242, 0, 0, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 0, -163, 0, -163, -163, -163, -163, -163, 0, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 0, 0, 0, -163, -163, -163, -163, -163, -163, 0, -163, 0, 0, 0, 0, 0, 0, 0, 0, -163, 0, 0, -163, -163, 0, -163, 0, -163, -163, 0, 0, 0, -163, -163, 0, 0, 0, 0, 0, 0, 0, 0, 0, -163, -163, -163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 536 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -851, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 0, -242, 0, -242, -242, -242, -242, -242, 0, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 0, 0, 0, -242, -242, -242, -242, -242, -242, 0, -242, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, 0, -242, -242, 0, -242, 0, -242, -242, 0, 0, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 537 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 538 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 665, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 539 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -842, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -842, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 540 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -841, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -841, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 541 - -764, -764, -764, -764, -764, -764, -764, 0, -764, -764, 0, -764, -764, -764, -764, -764, -764, -764, 0, 0, 0, -764, -764, -764, -764, -764, 0, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, 0, 0, 0, 0, -764, -764, -764, -764, -764, 0, -764, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, 0, -764, -764, 0, -764, 0, -764, -764, 0, 0, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -853, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 542 - -141, -141, -141, 0, -141, 0, -141, 0, -141, 0, 0, -141, -141, 0, -141, -141, 0, -141, 0, 0, 0, 0, 0, -141, -141, -141, 0, -141, -141, 0, -141, -141, -141, -141, -141, -141, 0, -141, 0, 0, -141, 0, 0, 0, 0, -141, 0, -141, -141, -141, 0, -141, 0, 0, 0, 0, 0, 0, 0, 0, -141, 0, 0, -141, -141, 0, -141, 0, -141, -141, 0, 0, 0, -141, -141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -141, -141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -765, -765, -765, -765, -765, -765, -765, 0, -765, -765, 0, -765, -765, -765, -765, -765, -765, -765, 0, 0, 0, -765, -765, -765, -765, -765, 0, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, 0, 0, 0, 0, -765, -765, -765, -765, -765, 0, -765, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, 0, -765, -765, 0, -765, 0, -765, -765, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 543 - 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, 0, 0, -302, 0, 0, -302, 0, 0, 0, -302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -302, -302, -302, -302, 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, -302, 0, 0, -302, 0, 0, 0, -302, -302, 0, -302, 0, -302, -302, + -141, -141, -141, 0, -141, 0, -141, 0, -141, 0, 0, -141, -141, 0, -141, -141, 0, -141, 0, 0, 0, 0, 0, -141, -141, -141, 0, -141, -141, 0, -141, -141, -141, -141, -141, -141, 0, -141, 0, 0, -141, 0, 0, 0, 0, -141, 0, -141, -141, -141, 0, -141, 0, 0, 0, 0, 0, 0, 0, 0, -141, 0, 0, -141, -141, 0, -141, 0, -141, -141, 0, 0, 0, -141, -141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, -141, -141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 544 - 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, 0, 0, -300, 0, 0, -300, 0, 0, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -300, -300, -300, -300, 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, -300, 0, 0, -300, 0, 0, 0, -300, -300, 0, -300, 0, -300, -300, + 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, 0, 0, -302, 0, 0, -302, 0, 0, 0, -302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -302, -302, -302, -302, 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, -302, 0, 0, -302, 0, 0, 0, -302, -302, 0, -302, 0, -302, -302, // State 545 - -348, -348, -348, 0, -348, 0, -348, 0, -348, 0, 0, -348, -348, 0, -348, -348, 0, -348, 0, 0, 0, 0, 0, -348, -348, -348, 0, -348, -348, 0, -348, -348, -348, -348, -348, -348, 0, -348, -348, 0, -348, 0, 0, 0, 0, -348, 36, -348, -348, -348, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, 0, -348, -348, 0, -348, 0, -348, -348, 0, 0, 0, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, 0, 0, -300, 0, 0, -300, 0, 0, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -300, -300, -300, -300, 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, -300, 0, 0, -300, 0, 0, 0, -300, -300, 0, -300, 0, -300, -300, // State 546 - -91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -348, -348, -348, 0, -348, 0, -348, 0, -348, 0, 0, -348, -348, 0, -348, -348, 0, -348, 0, 0, 0, 0, 0, -348, -348, -348, 0, -348, -348, 0, -348, -348, -348, -348, -348, -348, 0, -348, -348, 0, -348, 0, 0, 0, 0, -348, 37, -348, -348, -348, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, 0, -348, -348, 0, -348, 0, -348, -348, 0, 0, 0, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 547 - -551, -551, 0, 0, -551, 0, -551, 0, -551, 0, 0, -551, -551, 0, -551, -551, 0, -551, 0, 0, 0, 0, 0, -551, -551, -551, 0, -551, 0, 0, -551, 0, -551, 0, 0, 0, 0, -551, 0, 0, -551, 0, 0, 0, 0, 0, 0, -551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -551, -551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 548 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -552, -552, 0, 0, -552, 0, -552, 0, -552, 0, 0, -552, -552, 0, -552, -552, 0, -552, 0, 0, 0, 0, 0, -552, -552, -552, 0, -552, 0, 0, -552, 0, -552, 0, 0, 0, 0, -552, 0, 0, -552, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 549 - -860, -860, -860, -860, -860, -860, -860, 0, -860, -860, 0, -860, -860, -860, -860, -860, -860, -860, 0, 0, 0, -860, -860, -860, -860, -860, 0, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, 0, 0, 0, 0, -860, -860, -860, -860, -860, 0, -860, 0, 0, 0, 0, 0, 0, 0, 0, -860, 0, 0, -860, -860, 0, -860, 0, -860, -860, 0, 0, 0, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, -860, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 550 - -942, -942, -942, 0, -942, 23, -942, 0, -942, 0, 0, -942, -942, 0, -942, -942, 0, -942, 0, 0, 0, 0, 0, -942, -942, -942, 0, -942, -942, 0, -942, -942, -942, -942, -942, -942, 0, -942, -942, 0, -942, 0, 0, 0, 0, -942, -942, -942, -942, -942, 0, -942, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, 0, -942, -942, 0, -942, 0, -942, -942, 0, 0, 0, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -859, -859, -859, -859, -859, -859, -859, 0, -859, -859, 0, -859, -859, -859, -859, -859, -859, -859, 0, 0, 0, -859, -859, -859, -859, -859, 0, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, 0, 0, 0, 0, -859, -859, -859, -859, -859, 0, -859, 0, 0, 0, 0, 0, 0, 0, 0, -859, 0, 0, -859, -859, 0, -859, 0, -859, -859, 0, 0, 0, -859, -859, 0, 0, 0, 0, 0, 0, 0, 0, 0, -859, -859, -859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 551 - 0, 0, 0, 0, 0, 0, 0, 0, 667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -945, -945, -945, 0, -945, 24, -945, 0, -945, 0, 0, -945, -945, 0, -945, -945, 0, -945, 0, 0, 0, 0, 0, -945, -945, -945, 0, -945, -945, 0, -945, -945, -945, -945, -945, -945, 0, -945, -945, 0, -945, 0, 0, 0, 0, -945, -945, -945, -945, -945, 0, -945, 0, 0, 0, 0, 0, 0, 0, 0, -945, 0, 0, -945, -945, 0, -945, 0, -945, -945, 0, 0, 0, -945, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, -945, -945, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 552 - 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 553 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 554 - 0, 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 555 - -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 0, -196, 0, -196, -196, -196, -196, -196, 0, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 0, 0, 0, -196, -196, -196, -196, -196, -196, 0, -196, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, 0, -196, -196, 0, -196, 0, -196, -196, 0, 0, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 672, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 556 - -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 0, -190, 0, -190, -190, -190, -190, -190, 0, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 0, 0, 0, -190, -190, -190, -190, -190, -190, 0, -190, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, 0, -190, -190, 0, -190, 0, -190, -190, 0, 0, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 0, -196, 0, -196, -196, -196, -196, -196, 0, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 0, 0, 0, -196, -196, -196, -196, -196, -196, 0, -196, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, 0, -196, -196, 0, -196, 0, -196, -196, 0, 0, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 557 - -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 0, -200, 0, -200, -200, -200, -200, -200, 0, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 0, 0, 0, -200, -200, -200, -200, -200, -200, 0, -200, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, -200, -200, 0, -200, 0, -200, -200, 0, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 0, -190, 0, -190, -190, -190, -190, -190, 0, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 0, 0, 0, -190, -190, -190, -190, -190, -190, 0, -190, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, 0, -190, -190, 0, -190, 0, -190, -190, 0, 0, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 558 - 0, 0, 0, 0, 0, 0, 0, 0, 676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 0, -200, 0, -200, -200, -200, -200, -200, 0, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 0, 0, 0, -200, -200, -200, -200, -200, -200, 0, -200, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, -200, -200, 0, -200, 0, -200, -200, 0, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 559 - -946, -946, 0, 0, 0, 0, 0, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, -946, 0, 0, 0, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 560 - -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 0, -186, 0, -186, -186, -186, -186, -186, 0, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 0, 0, 0, -186, -186, -186, -186, -186, -186, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, -186, -186, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -949, -949, 0, 0, 0, 0, 0, 0, -949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -949, 0, -949, 0, 0, 0, 0, -949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 561 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 0, -186, 0, -186, -186, -186, -186, -186, 0, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 0, 0, 0, -186, -186, -186, -186, -186, -186, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, -186, -186, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 562 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 563 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 564 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -822, 0, 0, 0, 0, 0, 0, 0, 0, 0, -822, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, -726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 565 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -459, 0, 0, 0, 0, 0, 0, 0, 0, 0, -459, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -823, 0, 0, 0, 0, 0, 0, 0, 0, 0, -823, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 566 - -464, -464, 0, 0, -464, 0, -464, 0, -464, 0, 0, -464, -464, 0, -464, -464, 0, -464, 0, 0, 0, 0, 0, -464, -464, -464, 0, -464, 0, 0, -464, 0, -464, 0, 0, 0, 0, -464, 0, 0, -464, 0, 0, 0, 0, -464, 0, -464, 0, -464, 0, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -464, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -464, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -459, 0, 0, 0, 0, 0, 0, 0, 0, 0, -459, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 567 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -464, -464, 0, 0, -464, 0, -464, 0, -464, 0, 0, -464, -464, 0, -464, -464, 0, -464, 0, 0, 0, 0, 0, -464, -464, -464, 0, -464, 0, 0, -464, 0, -464, 0, 0, 0, 0, -464, 0, 0, -464, 0, 0, 0, 0, -464, 0, -464, 0, -464, 0, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -464, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -464, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 568 - -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 0, -203, 0, -203, -203, -203, -203, -203, 0, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 0, 0, 0, -203, -203, -203, -203, -203, -203, 0, -203, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, 0, -203, -203, 0, -203, 0, -203, -203, 0, 0, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 690, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 569 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 689, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 0, -203, 0, -203, -203, -203, -203, -203, 0, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 0, 0, 0, -203, -203, -203, -203, -203, -203, 0, -203, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, 0, -203, -203, 0, -203, 0, -203, -203, 0, 0, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 570 - -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 0, -206, 0, -206, -206, -206, -206, -206, 0, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 0, 0, 0, -206, -206, -206, -206, -206, -206, 0, -206, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, 0, -206, -206, 0, -206, 0, -206, -206, 0, 0, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 691, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 571 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, -327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 0, -206, 0, -206, -206, -206, -206, -206, 0, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 0, 0, 0, -206, -206, -206, -206, -206, -206, 0, -206, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, 0, -206, -206, 0, -206, 0, -206, -206, 0, 0, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 572 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -378, 0, 0, -378, 0, 0, -378, 0, 0, 0, 0, 0, 0, -378, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, -327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 573 - -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 0, -367, 0, -367, -367, -367, -367, -367, 0, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 0, 0, 0, -367, -367, -367, -367, -367, -367, 0, -367, 0, 0, 0, 0, 0, 0, 0, 0, -367, 0, 0, -367, -367, 0, -367, 0, -367, -367, 0, 0, 0, -367, -367, 0, 0, 0, 0, 0, 0, 0, 0, 0, -367, -367, -367, 0, 0, 0, -367, 0, 0, 0, 0, 0, 0, 0, 0, 0, -367, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -378, 0, 0, -378, 0, 0, -378, 0, 0, 0, 0, 0, 0, -378, 0, 0, 0, 0, // State 574 - -875, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -875, 0, -875, 0, 0, 0, 0, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 0, -367, 0, -367, -367, -367, -367, -367, 0, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, -367, 0, 0, 0, -367, -367, -367, -367, -367, -367, 0, -367, 0, 0, 0, 0, 0, 0, 0, 0, -367, 0, 0, -367, -367, 0, -367, 0, -367, -367, 0, 0, 0, -367, -367, 0, 0, 0, 0, 0, 0, 0, 0, 0, -367, -367, -367, 0, 0, 0, -367, 0, 0, 0, 0, 0, 0, 0, 0, 0, -367, // State 575 - -876, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -876, 0, -876, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -874, -874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -874, 0, -874, 0, 0, 0, 0, -874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 576 - 697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -875, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -875, 0, -875, 0, 0, 0, 0, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 577 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, -324, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 578 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, -324, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 579 - -456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 580 - -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 701, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 581 - -179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -179, 0, 0, 0, 0, -179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 582 - 0, 0, 0, 0, 0, 0, 0, -256, 0, -256, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, -256, -256, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, -256, -256, 0, -256, 0, -256, -256, + -179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -179, 0, 0, 0, 0, -179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 583 - 0, 0, 0, 0, 0, 0, 0, -257, 0, -257, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -257, -257, -257, -257, 0, 0, 0, 0, 0, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, -257, -257, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, -257, -257, 0, -257, 0, -257, -257, + 0, 0, 0, 0, 0, 0, 0, -256, 0, -256, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, -256, -256, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, -256, -256, 0, -256, 0, -256, -256, // State 584 - 0, 0, 0, 0, 0, 0, 0, -262, 0, -262, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -262, -262, -262, -262, 0, 0, 0, 0, 0, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, -262, -262, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, -262, -262, 0, -262, 0, -262, -262, + 0, 0, 0, 0, 0, 0, 0, -257, 0, -257, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -257, -257, -257, -257, 0, 0, 0, 0, 0, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, -257, -257, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, -257, -257, 0, -257, 0, -257, -257, // State 585 - 0, 0, 0, 0, 0, 0, 0, -253, 0, -253, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -253, -253, -253, -253, 0, 0, 0, 0, 0, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, -253, -253, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, -253, -253, 0, -253, 0, -253, -253, + 0, 0, 0, 0, 0, 0, 0, -262, 0, -262, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -262, -262, -262, -262, 0, 0, 0, 0, 0, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, -262, -262, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, -262, -262, 0, -262, 0, -262, -262, // State 586 - 0, 0, 0, 0, 0, 0, 0, -251, 0, -251, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -251, -251, -251, -251, 0, 0, 0, 0, 0, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, -251, -251, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, -251, -251, 0, -251, 0, -251, -251, + 0, 0, 0, 0, 0, 0, 0, -253, 0, -253, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -253, -253, -253, -253, 0, 0, 0, 0, 0, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, -253, -253, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, -253, -253, 0, -253, 0, -253, -253, // State 587 - 0, 0, 0, 0, 0, 0, 0, -252, 0, -252, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -252, -252, -252, -252, 0, 0, 0, 0, 0, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, -252, -252, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, -252, -252, 0, -252, 0, -252, -252, + 0, 0, 0, 0, 0, 0, 0, -251, 0, -251, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -251, -251, -251, -251, 0, 0, 0, 0, 0, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, -251, -251, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, -251, -251, 0, -251, 0, -251, -251, // State 588 - 0, 0, 0, 0, 0, 0, 0, -263, 0, -263, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -263, -263, -263, -263, 0, 0, 0, 0, 0, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, -263, -263, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, -263, -263, 0, -263, 0, -263, -263, + 0, 0, 0, 0, 0, 0, 0, -252, 0, -252, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -252, -252, -252, -252, 0, 0, 0, 0, 0, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, -252, -252, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, -252, -252, 0, -252, 0, -252, -252, // State 589 - 0, 0, 0, 0, 0, 0, 0, -255, 0, -255, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, -255, -255, -255, 0, 0, 0, 0, 0, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, -255, -255, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, -255, -255, 0, -255, 0, -255, -255, + 0, 0, 0, 0, 0, 0, 0, -263, 0, -263, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -263, -263, -263, -263, 0, 0, 0, 0, 0, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, -263, -263, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, -263, -263, 0, -263, 0, -263, -263, // State 590 - 0, 0, 0, 0, 0, 0, 0, -260, 0, -260, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -260, -260, -260, -260, 0, 0, 0, 0, 0, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, -260, -260, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, -260, -260, 0, -260, 0, -260, -260, + 0, 0, 0, 0, 0, 0, 0, -255, 0, -255, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, -255, -255, -255, 0, 0, 0, 0, 0, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, -255, -255, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, -255, -255, 0, -255, 0, -255, -255, // State 591 - 0, 0, 0, 0, 0, 0, 0, -261, 0, -261, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -261, -261, -261, -261, 0, 0, 0, 0, 0, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, -261, -261, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, -261, -261, 0, -261, 0, -261, -261, + 0, 0, 0, 0, 0, 0, 0, -260, 0, -260, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -260, -260, -260, -260, 0, 0, 0, 0, 0, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, -260, -260, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, -260, -260, 0, -260, 0, -260, -260, // State 592 - 0, 0, 0, 0, 0, 0, 0, -254, 0, -254, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, -254, -254, -254, 0, 0, 0, 0, 0, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, -254, -254, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, -254, -254, 0, -254, 0, -254, -254, + 0, 0, 0, 0, 0, 0, 0, -261, 0, -261, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -261, -261, -261, -261, 0, 0, 0, 0, 0, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, -261, -261, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, -261, -261, 0, -261, 0, -261, -261, // State 593 - 0, 0, 0, 0, 0, 0, 0, -259, 0, -259, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, -259, -259, -259, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, -259, -259, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, -259, -259, 0, -259, 0, -259, -259, + 0, 0, 0, 0, 0, 0, 0, -254, 0, -254, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, -254, -254, -254, 0, 0, 0, 0, 0, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, -254, -254, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, -254, -254, 0, -254, 0, -254, -254, // State 594 - 0, 0, 0, 0, 0, 0, 0, -258, 0, -258, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -258, -258, -258, -258, 0, 0, 0, 0, 0, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, -258, -258, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, -258, -258, 0, -258, 0, -258, -258, + 0, 0, 0, 0, 0, 0, 0, -259, 0, -259, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, -259, -259, -259, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, -259, -259, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, -259, -259, 0, -259, 0, -259, -259, // State 595 - -772, 0, 0, 0, 0, 0, 0, -772, 0, -772, 0, 0, 0, -772, 0, 0, -772, 0, 0, 0, -772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -772, 0, -772, -772, -772, -772, 0, 0, 0, 0, 0, -772, -772, -772, -772, 0, -772, -772, -772, -772, 0, 0, 0, 0, -772, -772, -772, -772, -772, 0, 0, -772, -772, -772, -772, 0, -772, -772, -772, -772, -772, -772, -772, -772, -772, 0, 0, 0, -772, 0, 0, -772, 0, 0, 0, -772, -772, 0, -772, -772, -772, -772, + 0, 0, 0, 0, 0, 0, 0, -258, 0, -258, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -258, -258, -258, -258, 0, 0, 0, 0, 0, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, -258, -258, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, -258, -258, 0, -258, 0, -258, -258, // State 596 - 705, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, + -773, 0, 0, 0, 0, 0, 0, -773, 0, -773, 0, 0, 0, -773, 0, 0, -773, 0, 0, 0, -773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -773, 0, -773, -773, -773, -773, 0, 0, 0, 0, 0, -773, -773, -773, -773, 0, -773, -773, -773, -773, 0, 0, 0, 0, -773, -773, -773, -773, -773, 0, 0, -773, -773, -773, -773, 0, -773, -773, -773, -773, -773, -773, -773, -773, -773, 0, 0, 0, -773, 0, 0, -773, 0, 0, 0, -773, -773, 0, -773, -773, -773, -773, // State 597 - 706, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 707, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, // State 598 - -174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 599 - -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 600 - -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 601 - -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 602 - -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 603 - -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 604 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 605 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 606 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 607 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 608 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -447, -447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -447, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 609 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -447, -447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -447, 0, // State 610 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -444, -444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -444, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 611 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -443, -443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -443, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -444, -444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -444, 0, // State 612 - -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -443, -443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -443, 0, // State 613 - -428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 614 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 615 - -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 616 - -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 617 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 714, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 618 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 716, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 619 - -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 620 - -777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 621 - -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 622 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 623 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 624 - 0, 0, -943, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, 0, -943, 0, -943, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, -943, -943, 0, 0, 0, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 625 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -946, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, 0, -946, 0, -946, -946, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, -946, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, -946, -946, 0, 0, 0, -946, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 626 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 627 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 628 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 629 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 630 - 0, 0, -765, -765, 0, -765, 0, 0, 0, -765, 177, 0, 0, -765, 0, -765, -765, 0, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, -765, -765, 0, -765, 0, -765, -765, -765, -765, 0, 0, -765, 0, 0, 0, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 631 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -766, -766, 0, -766, 0, 0, 0, -766, 177, 0, 0, -766, 0, -766, -766, 0, 0, 0, 0, -766, -766, 0, 0, 0, 0, 0, -766, -766, 0, -766, 0, -766, -766, -766, -766, 0, 0, -766, 0, 0, 0, 0, 0, 0, -766, 0, -766, -766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -766, 0, -766, -766, 0, 0, 0, -766, -766, 0, 0, 0, 0, 0, 0, 0, 0, 0, -766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 632 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 633 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -518, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 634 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 635 - 0, 0, -185, -185, 0, -185, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -214, 0, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, 0, -185, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 636 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, -871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -185, -185, 0, -185, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -214, 0, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, 0, -185, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 637 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, -870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 638 - 0, 0, -184, -184, 0, -184, 0, -184, 0, -184, -184, 0, 0, -184, 0, -184, -184, 0, 0, -184, 0, -184, -184, 0, 0, -213, 0, 0, -184, -184, 0, -184, 0, -184, -184, -184, -184, 0, 0, -184, 0, 0, 0, 0, -184, 0, -184, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, -184, -184, 0, 0, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 639 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -184, -184, 0, -184, 0, -184, 0, -184, -184, 0, 0, -184, 0, -184, -184, 0, 0, -184, 0, -184, -184, 0, 0, -213, 0, 0, -184, -184, 0, -184, 0, -184, -184, -184, -184, 0, 0, -184, 0, 0, 0, 0, -184, 0, -184, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, -184, -184, 0, 0, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 640 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 641 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 642 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 643 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 644 - 0, 0, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -183, -183, 0, -183, 0, -183, 0, -183, -183, 0, 0, -183, 0, -183, -183, 0, 0, -183, 0, -183, -183, 0, 0, -212, 0, 0, -183, -183, 0, -183, 0, -183, -183, -183, -183, 0, 0, -183, 0, 0, 0, 0, -183, 0, -183, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, -183, -183, 0, 0, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 645 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 646 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -925, 0, 0, 0, 0, 0, 0, -925, 0, 0, 0, 0, 0, 0, 0, 0, 0, -925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 647 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, 0, 0, 0, -925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -927, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 648 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 649 - 0, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, 0, -349, 0, -349, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, -349, -349, 0, 0, 0, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, 0, 0, 0, -928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 650 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 651 - 0, 0, -211, -211, 0, -211, 0, -211, 0, -211, -211, 0, 0, -211, 0, -211, -211, 0, 0, -211, 0, -211, -211, 0, 0, -238, 0, 0, -211, -211, 0, -211, 0, -211, -211, -211, -211, 0, 0, -211, 0, 0, 0, 0, -211, 0, -211, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, -211, -211, 0, 0, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, 0, -349, 0, -349, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, -349, -349, 0, 0, 0, -349, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 652 - 0, 0, -209, -209, 0, -209, 0, -209, 0, -209, -209, 0, 0, -209, 0, -209, -209, 0, 0, -209, 0, -209, -209, 0, 0, -236, 0, 0, -209, -209, 0, -209, 0, -209, -209, -209, -209, 0, 0, -209, 0, 0, 0, 0, -209, 0, -209, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, -209, -209, 0, 0, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 653 - 0, 0, -210, -210, 0, -210, 0, -210, 0, -210, -210, 0, 0, -210, 0, -210, -210, 0, 0, -210, 0, -210, -210, 0, 0, -237, 0, 0, -210, -210, 0, -210, 0, -210, -210, -210, -210, 0, 0, -210, 0, 0, 0, 0, -210, 0, -210, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, -210, -210, 0, 0, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -211, -211, 0, -211, 0, -211, 0, -211, -211, 0, 0, -211, 0, -211, -211, 0, 0, -211, 0, -211, -211, 0, 0, -238, 0, 0, -211, -211, 0, -211, 0, -211, -211, -211, -211, 0, 0, -211, 0, 0, 0, 0, -211, 0, -211, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, -211, -211, 0, 0, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 654 - 0, 0, -208, -208, 0, -208, 0, -208, 0, -208, -208, 0, 0, -208, 0, -208, -208, 0, 0, -208, 0, -208, -208, 0, 0, -235, 0, 0, -208, -208, 0, -208, 0, -208, -208, -208, -208, 0, 0, -208, 0, 0, 0, 0, -208, 0, -208, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, -208, -208, 0, 0, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -209, -209, 0, -209, 0, -209, 0, -209, -209, 0, 0, -209, 0, -209, -209, 0, 0, -209, 0, -209, -209, 0, 0, -236, 0, 0, -209, -209, 0, -209, 0, -209, -209, -209, -209, 0, 0, -209, 0, 0, 0, 0, -209, 0, -209, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, -209, -209, 0, 0, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 655 - 0, 0, 0, 0, 0, 0, 0, 0, 734, 0, 0, 0, 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -210, -210, 0, -210, 0, -210, 0, -210, -210, 0, 0, -210, 0, -210, -210, 0, 0, -210, 0, -210, -210, 0, 0, -237, 0, 0, -210, -210, 0, -210, 0, -210, -210, -210, -210, 0, 0, -210, 0, 0, 0, 0, -210, 0, -210, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, -210, -210, 0, 0, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 656 - -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 0, -165, 0, -165, -165, -165, -165, -165, 0, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 0, 0, 0, -165, -165, -165, -165, -165, -165, 0, -165, 0, 0, 0, 0, 0, 0, 0, 0, -165, 0, 0, -165, -165, 0, -165, 0, -165, -165, 0, 0, 0, -165, -165, 0, 0, 0, 0, 0, 0, 0, 0, 0, -165, -165, -165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -208, -208, 0, -208, 0, -208, 0, -208, -208, 0, 0, -208, 0, -208, -208, 0, 0, -208, 0, -208, -208, 0, 0, -235, 0, 0, -208, -208, 0, -208, 0, -208, -208, -208, -208, 0, 0, -208, 0, 0, 0, 0, -208, 0, -208, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, -208, -208, 0, 0, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 657 - -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 0, -162, 0, -162, -162, -162, -162, -162, 0, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 0, 0, 0, -162, -162, -162, -162, -162, -162, 0, -162, 0, 0, 0, 0, 0, 0, 0, 0, -162, 0, 0, -162, -162, 0, -162, 0, -162, -162, 0, 0, 0, -162, -162, 0, 0, 0, 0, 0, 0, 0, 0, 0, -162, -162, -162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 736, 0, 0, 0, 0, 0, 0, 737, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 658 - 0, 0, 0, 0, 0, 0, 0, -118, -118, -118, -118, 0, 0, -118, 0, 0, -118, 0, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, -118, -118, -118, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, 0, -118, 0, 0, -118, 0, 0, 0, -118, -118, 0, -118, 0, -118, -118, + -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 0, -165, 0, -165, -165, -165, -165, -165, 0, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 0, 0, 0, -165, -165, -165, -165, -165, -165, 0, -165, 0, 0, 0, 0, 0, 0, 0, 0, -165, 0, 0, -165, -165, 0, -165, 0, -165, -165, 0, 0, 0, -165, -165, 0, 0, 0, 0, 0, 0, 0, 0, 0, -165, -165, -165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 659 - 0, 0, 0, 0, 0, 0, 0, 0, -417, 0, 0, 0, 0, 0, 0, -417, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 0, -162, 0, -162, -162, -162, -162, -162, 0, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 0, 0, 0, -162, -162, -162, -162, -162, -162, 0, -162, 0, 0, 0, 0, 0, 0, 0, 0, -162, 0, 0, -162, -162, 0, -162, 0, -162, -162, 0, 0, 0, -162, -162, 0, 0, 0, 0, 0, 0, 0, 0, 0, -162, -162, -162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 660 - 0, 0, 0, 0, 0, 0, 0, 0, -420, 0, 0, 0, 0, 0, 0, -420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -118, -118, -118, -118, 0, 0, -118, 0, 0, -118, 0, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, -118, -118, -118, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, 0, -118, 0, 0, -118, 0, 0, 0, -118, -118, 0, -118, 0, -118, -118, // State 661 - 0, 0, 0, 0, 0, 0, 0, 0, -421, 0, 0, 0, 0, 0, 0, -421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -417, 0, 0, 0, 0, 0, 0, -417, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 662 - -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 0, -241, 0, -241, -241, -241, -241, -241, 0, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 0, 0, 0, -241, -241, -241, -241, -241, -241, 0, -241, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, 0, -241, -241, 0, -241, 0, -241, -241, 0, 0, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -420, 0, 0, 0, 0, 0, 0, -420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 663 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -421, 0, 0, 0, 0, 0, 0, -421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 664 - -142, -142, -142, 0, -142, 0, -142, 0, -142, 0, 0, -142, -142, 0, -142, -142, 0, -142, 0, 0, 0, 0, 0, -142, -142, -142, 0, -142, -142, 0, -142, -142, -142, -142, -142, -142, 0, -142, 0, 0, -142, 0, 0, 0, 0, -142, 0, -142, -142, -142, 0, -142, 0, 0, 0, 0, 0, 0, 0, 0, -142, 0, 0, -142, -142, 0, -142, 0, -142, -142, 0, 0, 0, -142, -142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -142, -142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 0, -241, 0, -241, -241, -241, -241, -241, 0, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 0, 0, 0, -241, -241, -241, -241, -241, -241, 0, -241, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, 0, -241, -241, 0, -241, 0, -241, -241, 0, 0, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 665 - -507, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 666 - -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 0, -201, 0, -201, -201, -201, -201, -201, 0, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 0, 0, 0, -201, -201, -201, -201, -201, -201, 0, -201, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, 0, -201, -201, 0, -201, 0, -201, -201, 0, 0, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -142, -142, -142, 0, -142, 0, -142, 0, -142, 0, 0, -142, -142, 0, -142, -142, 0, -142, 0, 0, 0, 0, 0, -142, -142, -142, 0, -142, -142, 0, -142, -142, -142, -142, -142, -142, 0, -142, 0, 0, -142, 0, 0, 0, 0, -142, 0, -142, -142, -142, 0, -142, 0, 0, 0, 0, 0, 0, 0, 0, -142, 0, 0, -142, -142, 0, -142, 0, -142, -142, 0, 0, 0, -142, -142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, -142, -142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 667 - 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -508, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 668 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 0, -201, 0, -201, -201, -201, -201, -201, 0, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 0, 0, 0, -201, -201, -201, -201, -201, -201, 0, -201, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, 0, -201, -201, 0, -201, 0, -201, -201, 0, 0, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 669 - -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 0, -198, 0, -198, -198, -198, -198, -198, 0, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 0, 0, 0, -198, -198, -198, -198, -198, -198, 0, -198, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, 0, -198, -198, 0, -198, 0, -198, -198, 0, 0, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 670 - 0, 0, 0, 0, 0, 0, 0, 0, -65, 0, 0, 0, 0, 0, 0, -65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 671 - -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 0, -192, 0, -192, -192, -192, -192, -192, 0, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 0, 0, 0, -192, -192, -192, -192, -192, -192, 0, -192, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 0, -192, -192, 0, -192, 0, -192, -192, 0, 0, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 0, -198, 0, -198, -198, -198, -198, -198, 0, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 0, 0, 0, -198, -198, -198, -198, -198, -198, 0, -198, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, 0, -198, -198, 0, -198, 0, -198, -198, 0, 0, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 672 - 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -65, 0, 0, 0, 0, 0, 0, -65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 673 - 0, 0, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 0, -192, 0, -192, -192, -192, -192, -192, 0, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 0, 0, 0, -192, -192, -192, -192, -192, -192, 0, -192, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 0, -192, -192, 0, -192, 0, -192, -192, 0, 0, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 674 - -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 0, -189, 0, -189, -189, -189, -189, -189, 0, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 0, 0, 0, -189, -189, -189, -189, -189, -189, 0, -189, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, 0, -189, -189, 0, -189, 0, -189, -189, 0, 0, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 675 - -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 0, -202, 0, -202, -202, -202, -202, -202, 0, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 0, 0, 0, -202, -202, -202, -202, -202, -202, 0, -202, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, -202, -202, 0, -202, 0, -202, -202, 0, 0, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -550, 0, 0, 0, 0, 0, 0, -550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 676 - -948, -948, 0, 0, 0, 0, 0, 0, -948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -948, 0, -948, 0, 0, 0, 0, -948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 0, -189, 0, -189, -189, -189, -189, -189, 0, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 0, 0, 0, -189, -189, -189, -189, -189, -189, 0, -189, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, 0, -189, -189, 0, -189, 0, -189, -189, 0, 0, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 677 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 0, -202, 0, -202, -202, -202, -202, -202, 0, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 0, 0, 0, -202, -202, -202, -202, -202, -202, 0, -202, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, -202, -202, 0, -202, 0, -202, -202, 0, 0, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 678 - -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 0, -188, 0, -188, -188, -188, -188, -188, 0, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 0, 0, 0, -188, -188, -188, -188, -188, -188, 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, 0, -188, -188, 0, -188, 0, -188, -188, 0, 0, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -951, -951, 0, 0, 0, 0, 0, 0, -951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -951, 0, -951, 0, 0, 0, 0, -951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 679 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 748, 0, 0, 0, 0, 0, 0, 0, 0, 0, -707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 680 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -545, 0, 0, 0, 0, 0, 0, 0, 0, 0, -545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 0, -188, 0, -188, -188, -188, -188, -188, 0, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 0, 0, 0, -188, -188, -188, -188, -188, -188, 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, 0, -188, -188, 0, -188, 0, -188, -188, 0, 0, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 681 - -462, -462, 0, 0, -462, 0, -462, 0, -462, 0, 0, -462, -462, 0, -462, -462, 0, -462, 0, 0, 0, 0, 0, -462, -462, -462, 0, -462, 0, 0, -462, 0, -462, 0, 0, 0, 0, -462, 0, 0, -462, 0, 0, 0, 0, -462, 0, -462, 0, -462, 0, -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -462, -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -462, -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 750, 0, 0, 0, 0, 0, 0, 0, 0, 0, -708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 682 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -565, 0, 0, 0, 0, 0, 0, 0, 0, 0, -565, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -546, 0, 0, 0, 0, 0, 0, 0, 0, 0, -546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 683 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -462, -462, 0, 0, -462, 0, -462, 0, -462, 0, 0, -462, -462, 0, -462, -462, 0, -462, 0, 0, 0, 0, 0, -462, -462, -462, 0, -462, 0, 0, -462, 0, -462, 0, 0, 0, 0, -462, 0, 0, -462, 0, 0, 0, 0, -462, 0, -462, 0, -462, 0, -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -462, -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -462, -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 684 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, -719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -566, 0, 0, 0, 0, 0, 0, 0, 0, 0, -566, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 685 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 686 - -463, -463, 0, 0, -463, 0, -463, 0, -463, 0, 0, -463, -463, 0, -463, -463, 0, -463, 0, 0, 0, 0, 0, -463, -463, -463, 0, -463, 0, 0, -463, 0, -463, 0, 0, 0, 0, -463, 0, 0, -463, 0, 0, 0, 0, -463, 0, -463, 0, -463, 0, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -463, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -463, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 757, 0, 0, 0, 0, 0, 0, 0, 0, 0, -720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 687 - -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 0, -205, 0, -205, -205, -205, -205, -205, 0, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 0, 0, 0, -205, -205, -205, -205, -205, -205, 0, -205, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, 0, -205, -205, 0, -205, 0, -205, -205, 0, 0, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 688 - -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 0, -207, 0, -207, -207, -207, -207, -207, 0, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 0, 0, 0, -207, -207, -207, -207, -207, -207, 0, -207, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, 0, -207, -207, 0, -207, 0, -207, -207, 0, 0, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -463, -463, 0, 0, -463, 0, -463, 0, -463, 0, 0, -463, -463, 0, -463, -463, 0, -463, 0, 0, 0, 0, 0, -463, -463, -463, 0, -463, 0, 0, -463, 0, -463, 0, 0, 0, 0, -463, 0, 0, -463, 0, 0, 0, 0, -463, 0, -463, 0, -463, 0, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -463, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -463, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 689 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 0, -205, 0, -205, -205, -205, -205, -205, 0, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 0, 0, 0, -205, -205, -205, -205, -205, -205, 0, -205, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, 0, -205, -205, 0, -205, 0, -205, -205, 0, 0, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 690 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 0, -207, 0, -207, -207, -207, -207, -207, 0, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 0, 0, 0, -207, -207, -207, -207, -207, -207, 0, -207, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, 0, -207, -207, 0, -207, 0, -207, -207, 0, 0, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 691 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 692 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 693 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 694 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 759, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 695 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -386, 0, 0, -386, 0, 0, -386, 0, 0, 0, 0, 0, 0, -386, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 696 - -773, 0, 0, 0, 0, 0, 0, -773, 0, -773, 0, 0, 0, -773, 0, 0, -773, 0, 0, 0, -773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -773, 0, -773, -773, -773, -773, 0, 0, 0, 0, 0, -773, -773, -773, -773, 0, -773, -773, -773, -773, 0, 0, 0, 0, -773, -773, -773, -773, -773, 0, 0, -773, -773, -773, -773, 0, -773, -773, -773, -773, -773, -773, -773, -773, -773, 0, 0, 0, -773, 0, 0, -773, 0, 0, 0, -773, -773, 0, -773, -773, -773, -773, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 761, 0, // State 697 - 763, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -386, 0, 0, -386, 0, 0, -386, 0, 0, 0, 0, 0, 0, -386, 0, 0, 0, 0, // State 698 - -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -774, 0, 0, 0, 0, 0, 0, -774, 0, -774, 0, 0, 0, -774, 0, 0, -774, 0, 0, 0, -774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -774, 0, -774, -774, -774, -774, 0, 0, 0, 0, 0, -774, -774, -774, -774, 0, -774, -774, -774, -774, 0, 0, 0, 0, -774, -774, -774, -774, -774, 0, 0, -774, -774, -774, -774, 0, -774, -774, -774, -774, -774, -774, -774, -774, -774, 0, 0, 0, -774, 0, 0, -774, 0, 0, 0, -774, -774, 0, -774, -774, -774, -774, // State 699 - -180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -180, 0, 0, 0, 0, -180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 765, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, // State 700 - -360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 701 - -176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -176, 0, 0, 0, 0, -176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -180, 0, 0, 0, 0, -180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 702 - -175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -175, 0, 0, 0, 0, -175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 703 - -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, 0, 0, 0, 0, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -176, 0, 0, 0, 0, -176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 704 - -770, 0, 0, 0, 0, 0, 0, -770, 0, -770, 0, 0, 0, -770, 0, 0, -770, 0, 0, 0, -770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -770, 0, -770, -770, -770, -770, 0, 0, 0, 0, 0, -770, -770, -770, -770, 0, -770, -770, -770, -770, 0, 0, 0, 0, -770, -770, -770, -770, -770, 0, 0, -770, -770, -770, -770, 0, -770, -770, -770, -770, -770, -770, -770, -770, -770, 0, 0, 0, -770, 0, 0, -770, 0, 0, 0, -770, -770, 0, -770, -770, -770, -770, + -175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -175, 0, 0, 0, 0, -175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 705 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, 0, -320, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, 0, 0, 0, 0, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 706 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -771, 0, 0, 0, 0, 0, 0, -771, 0, -771, 0, 0, 0, -771, 0, 0, -771, 0, 0, 0, -771, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -771, 0, -771, -771, -771, -771, 0, 0, 0, 0, 0, -771, -771, -771, -771, 0, -771, -771, -771, -771, 0, 0, 0, 0, -771, -771, -771, -771, -771, 0, 0, -771, -771, -771, -771, 0, -771, -771, -771, -771, -771, -771, -771, -771, -771, 0, 0, 0, -771, 0, 0, -771, 0, 0, 0, -771, -771, 0, -771, -771, -771, -771, // State 707 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, 0, -320, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 708 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 709 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 710 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 711 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -448, -448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -448, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 712 - -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 713 - 794, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -448, -448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -448, 0, // State 714 - 797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 715 - 800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 716 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 717 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 803, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 718 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, -560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 719 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, -160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 720 - 0, 0, -240, -240, 0, -240, 0, -240, 0, -240, -240, 0, 0, -240, 0, -240, -240, 0, 0, -240, 0, -240, -240, 0, 0, -244, 0, 0, -240, -240, 0, -240, 0, -240, -240, -240, -240, 0, 0, -240, 0, 0, 0, 0, -240, 0, -240, 0, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 0, -240, -240, 0, 0, 0, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -559, 0, 0, 0, 0, 0, 0, 0, 0, 0, -561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -559, 0, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 721 - 0, 0, -387, -387, 0, -387, 0, 0, 0, -387, 0, 0, 0, -387, 0, -387, -387, 0, 0, 0, 0, -387, -387, 0, 0, -389, 0, 0, -387, -387, 0, -387, 0, -387, -387, -387, -387, 0, 0, -387, 0, 0, 0, 0, 0, 0, -387, 0, -387, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -387, 0, -387, -387, 0, 0, 0, -387, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, -160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 722 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, -938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -240, -240, 0, -240, 0, -240, 0, -240, -240, 0, 0, -240, 0, -240, -240, 0, 0, -240, 0, -240, -240, 0, 0, -244, 0, 0, -240, -240, 0, -240, 0, -240, -240, -240, -240, 0, 0, -240, 0, 0, 0, 0, -240, 0, -240, 0, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 0, -240, -240, 0, 0, 0, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 723 - 0, 0, 0, 0, 0, 0, 0, 0, 821, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -387, -387, 0, -387, 0, 0, 0, -387, 0, 0, 0, -387, 0, -387, -387, 0, 0, 0, 0, -387, -387, 0, 0, -389, 0, 0, -387, -387, 0, -387, 0, -387, -387, -387, -387, 0, 0, -387, 0, 0, 0, 0, 0, 0, -387, 0, -387, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -387, 0, -387, -387, 0, 0, 0, -387, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 724 - 0, 0, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, -941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 725 - 0, 0, 0, 0, 0, 0, 0, 0, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 823, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 726 - 0, 0, -199, -199, 0, -199, 0, -199, 0, -199, -199, 0, 0, -199, 0, -199, -199, 0, 0, -199, 0, -199, -199, 0, 0, -226, 0, 0, -199, -199, 0, -199, 0, -199, -199, -199, -199, 0, 0, -199, 0, 0, 0, 0, -199, 0, -199, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, -199, -199, 0, 0, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 727 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 728 - 0, 0, -187, -187, 0, -187, 0, -187, 0, -187, -187, 0, 0, -187, 0, -187, -187, 0, 0, -187, 0, -187, -187, 0, 0, -216, 0, 0, -187, -187, 0, -187, 0, -187, -187, -187, -187, 0, 0, -187, 0, 0, 0, 0, -187, 0, -187, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, -187, -187, 0, 0, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -199, -199, 0, -199, 0, -199, 0, -199, -199, 0, 0, -199, 0, -199, -199, 0, 0, -199, 0, -199, -199, 0, 0, -226, 0, 0, -199, -199, 0, -199, 0, -199, -199, -199, -199, 0, 0, -199, 0, 0, 0, 0, -199, 0, -199, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, -199, -199, 0, 0, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 729 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -514, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -514, -514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -514, 0, 0, 0, 0, 0, 0, 0, -514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 730 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -187, -187, 0, -187, 0, -187, 0, -187, -187, 0, 0, -187, 0, -187, -187, 0, 0, -187, 0, -187, -187, 0, 0, -216, 0, 0, -187, -187, 0, -187, 0, -187, -187, -187, -187, 0, 0, -187, 0, 0, 0, 0, -187, 0, -187, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, -187, -187, 0, 0, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 731 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, -517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 732 - 0, 0, -204, -204, 0, -204, 0, -204, 0, -204, -204, 0, 0, -204, 0, -204, -204, 0, 0, -204, 0, -204, -204, 0, 0, -231, 0, 0, -204, -204, 0, -204, 0, -204, -204, -204, -204, 0, 0, -204, 0, 0, 0, 0, -204, 0, -204, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, -204, -204, 0, 0, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 733 - -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 0, -164, 0, -164, -164, -164, -164, -164, 0, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 0, 0, 0, -164, -164, -164, -164, -164, -164, 0, -164, 0, 0, 0, 0, 0, 0, 0, 0, -164, 0, 0, -164, -164, 0, -164, 0, -164, -164, 0, 0, 0, -164, -164, 0, 0, 0, 0, 0, 0, 0, 0, 0, -164, -164, -164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 734 - 0, 0, 0, 0, 0, 0, 0, -119, -119, -119, -119, 0, 0, -119, 0, 0, -119, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, -119, -119, -119, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, -119, 0, 0, -119, 0, 0, 0, -119, -119, 0, -119, 0, -119, -119, + 0, 0, -204, -204, 0, -204, 0, -204, 0, -204, -204, 0, 0, -204, 0, -204, -204, 0, 0, -204, 0, -204, -204, 0, 0, -231, 0, 0, -204, -204, 0, -204, 0, -204, -204, -204, -204, 0, 0, -204, 0, 0, 0, 0, -204, 0, -204, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, -204, -204, 0, 0, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 735 - 0, 0, 0, 0, 0, 0, 0, 0, -419, 0, 0, 0, 0, 0, 0, -419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 0, -164, 0, -164, -164, -164, -164, -164, 0, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 0, 0, 0, -164, -164, -164, -164, -164, -164, 0, -164, 0, 0, 0, 0, 0, 0, 0, 0, -164, 0, 0, -164, -164, 0, -164, 0, -164, -164, 0, 0, 0, -164, -164, 0, 0, 0, 0, 0, 0, 0, 0, 0, -164, -164, -164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 736 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -119, -119, -119, -119, 0, 0, -119, 0, 0, -119, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, -119, -119, -119, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, -119, 0, 0, -119, 0, 0, 0, -119, -119, 0, -119, 0, -119, -119, // State 737 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -419, 0, 0, 0, 0, 0, 0, -419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 738 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 739 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 740 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 741 - -864, -864, 0, 0, -864, 0, -864, 0, -864, 0, 0, -864, -864, 0, -864, -864, 0, -864, 0, 0, 0, 0, 0, -864, -864, -864, 0, -864, 0, 0, -864, 0, -864, 0, 0, 0, 0, -864, 0, 0, -864, 0, 0, 0, 0, -864, 0, -864, 0, -864, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 742 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 743 - 0, 0, 0, 0, 0, 0, 0, 0, -66, 0, 0, 0, 0, 0, 0, -66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -863, -863, 0, 0, -863, 0, -863, 0, -863, 0, 0, -863, -863, 0, -863, -863, 0, -863, 0, 0, 0, 0, 0, -863, -863, -863, 0, -863, 0, 0, -863, 0, -863, 0, 0, 0, 0, -863, 0, 0, -863, 0, 0, 0, 0, -863, 0, -863, 0, -863, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 744 - -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 0, -194, 0, -194, -194, -194, -194, -194, 0, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 0, 0, 0, -194, -194, -194, -194, -194, -194, 0, -194, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, 0, -194, -194, 0, -194, 0, -194, -194, 0, 0, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 745 - 0, 0, 0, 0, 0, 0, 0, 0, 833, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -66, 0, 0, 0, 0, 0, 0, -66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 746 - -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 0, -195, 0, -195, -195, -195, -195, -195, 0, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 0, 0, 0, -195, -195, -195, -195, -195, -195, 0, -195, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 0, -195, -195, 0, -195, 0, -195, -195, 0, 0, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 0, -194, 0, -194, -194, -194, -194, -194, 0, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 0, 0, 0, -194, -194, -194, -194, -194, -194, 0, -194, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, 0, -194, -194, 0, -194, 0, -194, -194, 0, 0, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 747 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 835, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 748 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, -698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 0, -195, 0, -195, -195, -195, -195, -195, 0, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 0, 0, 0, -195, -195, -195, -195, -195, -195, 0, -195, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 0, -195, -195, 0, -195, 0, -195, -195, 0, 0, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 749 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, -703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 750 - -461, -461, 0, 0, -461, 0, -461, 0, -461, 0, 0, -461, -461, 0, -461, -461, 0, -461, 0, 0, 0, 0, 0, -461, -461, -461, 0, -461, 0, 0, -461, 0, -461, 0, 0, 0, 0, -461, 0, 0, -461, 0, 0, 0, 0, -461, 0, -461, 0, -461, 0, -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -461, -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -461, -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, -699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 751 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 838, 0, 0, 0, 0, 0, 0, 0, 0, 0, -721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, -704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 752 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -461, -461, 0, 0, -461, 0, -461, 0, -461, 0, 0, -461, -461, 0, -461, -461, 0, -461, 0, 0, 0, 0, 0, -461, -461, -461, 0, -461, 0, 0, -461, 0, -461, 0, 0, 0, 0, -461, 0, 0, -461, 0, 0, 0, 0, -461, 0, -461, 0, -461, 0, -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -461, -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -461, -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 753 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 754 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 755 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 841, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 842, 0, 0, 0, 0, 0, 0, 0, 0, 0, -719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 756 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -384, 0, 0, -384, 0, 0, -384, 0, 0, 0, 0, 0, 0, -384, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -712, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 757 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -385, 0, 0, -385, 0, 0, -385, 0, 0, 0, 0, 0, 0, -385, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 758 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -384, 0, 0, -384, 0, 0, -384, 0, 0, 0, 0, 0, 0, -384, 0, 0, 0, 0, // State 759 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -385, 0, 0, -385, 0, 0, -385, 0, 0, 0, 0, 0, 0, -385, 0, 0, 0, 0, // State 760 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 761 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -382, 0, 0, -382, 0, 0, -382, 0, 0, 0, 0, 0, 0, -382, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 762 - -771, 0, 0, 0, 0, 0, 0, -771, 0, -771, 0, 0, 0, -771, 0, 0, -771, 0, 0, 0, -771, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -771, 0, -771, -771, -771, -771, 0, 0, 0, 0, 0, -771, -771, -771, -771, 0, -771, -771, -771, -771, 0, 0, 0, 0, -771, -771, -771, -771, -771, 0, 0, -771, -771, -771, -771, 0, -771, -771, -771, -771, -771, -771, -771, -771, -771, 0, 0, 0, -771, 0, 0, -771, 0, 0, 0, -771, -771, 0, -771, -771, -771, -771, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 763 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -382, 0, 0, -382, 0, 0, -382, 0, 0, 0, 0, 0, 0, -382, 0, 0, 0, 0, // State 764 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -772, 0, 0, 0, 0, 0, 0, -772, 0, -772, 0, 0, 0, -772, 0, 0, -772, 0, 0, 0, -772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -772, 0, -772, -772, -772, -772, 0, 0, 0, 0, 0, -772, -772, -772, -772, 0, -772, -772, -772, -772, 0, 0, 0, 0, -772, -772, -772, -772, -772, 0, 0, -772, -772, -772, -772, 0, -772, -772, -772, -772, -772, -772, -772, -772, -772, 0, 0, 0, -772, 0, 0, -772, 0, 0, 0, -772, -772, 0, -772, -772, -772, -772, // State 765 - -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 766 - -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 767 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 768 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 769 - -270, 0, 0, 0, 0, 0, 0, -270, 0, -270, 0, 0, 0, -270, 0, 0, -270, 0, 0, 0, -270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -270, 0, -270, -270, -270, -270, 0, 0, 0, 0, 0, -270, -270, -270, -270, 0, -270, -270, -270, -270, 0, 0, 0, 0, -270, -270, -270, -270, -270, 0, 0, -270, -270, -270, -270, 0, -270, -270, -270, -270, -270, -270, -270, -270, -270, 0, 0, 0, -270, -270, 0, -270, 0, 0, 0, -270, -270, 0, -270, -270, -270, -270, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 770 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 771 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -270, 0, 0, 0, 0, 0, 0, -270, 0, -270, 0, 0, 0, -270, 0, 0, -270, 0, 0, 0, -270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -270, 0, -270, -270, -270, -270, 0, 0, 0, 0, 0, -270, -270, -270, -270, 0, -270, -270, -270, -270, 0, 0, 0, 0, -270, -270, -270, -270, -270, 0, 0, -270, -270, -270, -270, 0, -270, -270, -270, -270, -270, -270, -270, -270, -270, 0, 0, 0, -270, -270, 0, -270, 0, 0, 0, -270, -270, 0, -270, -270, -270, -270, // State 772 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 773 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 774 - 0, 0, 0, 0, 0, 0, 0, 0, -914, 0, 0, 0, 0, 0, 0, -914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, -914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 775 - 0, 0, 0, 0, 0, 0, 0, 0, -649, 0, 0, 0, 0, 0, 0, 859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 776 - 0, 0, 0, 0, 0, 0, 0, 0, -623, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 777 - 0, 0, 0, 0, 0, 0, 0, 0, -542, 0, 0, 0, 0, 0, 0, -542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -650, 0, 0, 0, 0, 0, 0, 861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 778 - 0, 0, 0, 0, 0, 0, 0, 0, 860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -624, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 779 - 0, 0, 0, 0, 0, 0, 0, 0, -562, 0, 0, 0, 0, 0, 0, -562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -543, 0, 0, 0, 0, 0, 0, -543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 780 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -747, 0, 0, 0, 0, 0, 0, -747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 781 - -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -563, 0, 0, 0, 0, 0, 0, -563, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 782 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -748, 0, 0, 0, 0, 0, 0, -748, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 783 - -535, 0, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 784 - -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 785 - -439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -536, 0, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 786 - -442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 787 - -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 788 - -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 789 - -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 790 - -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 791 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -900, 0, 0, 0, 0, 0, 0, 0, 0, 0, -900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 792 - 869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 793 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -903, 0, 0, 0, 0, 0, 0, 0, 0, 0, -903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 794 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -901, 0, 0, 0, 0, 0, 0, 0, 0, 0, -901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 795 - 870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 796 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -904, 0, 0, 0, 0, 0, 0, 0, 0, 0, -904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 797 - -776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 798 - 871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 799 - -857, 0, 0, 0, 0, 0, 0, -857, 0, -857, 0, 0, 0, -857, 0, 0, -857, 0, 0, 0, -857, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -857, 0, -857, -857, -857, -857, 0, 0, 0, 0, 0, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, 0, 0, -857, -857, -857, -857, 0, -857, -857, -857, -857, -857, -857, -857, -857, -857, 0, 0, 0, -857, -857, 0, -857, 0, 0, 0, -857, -857, 0, -857, -857, -857, -857, + -777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 800 - 873, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, + 873, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 801 - -342, 0, 0, 0, 0, 0, 0, -342, 0, -342, 0, 0, 0, -342, 0, 0, -342, 0, 0, 0, -342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -342, 0, -342, -342, -342, -342, 0, 0, 0, 0, 0, -342, -342, -342, -342, 0, -342, -342, -342, -342, 0, -342, -342, -342, -342, -342, -342, -342, -342, 0, 0, -342, -342, -342, -342, 0, -342, -342, -342, -342, -342, -342, -342, -342, -342, 0, 0, 0, -342, -342, 0, -342, 0, 0, 0, -342, -342, 0, -342, -342, -342, -342, + -856, 0, 0, 0, 0, 0, 0, -856, 0, -856, 0, 0, 0, -856, 0, 0, -856, 0, 0, 0, -856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -856, 0, -856, -856, -856, -856, 0, 0, 0, 0, 0, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, 0, 0, -856, -856, -856, -856, 0, -856, -856, -856, -856, -856, -856, -856, -856, -856, 0, 0, 0, -856, -856, 0, -856, 0, 0, 0, -856, -856, 0, -856, -856, -856, -856, // State 802 - -346, 0, 0, 0, 0, 0, 0, -346, 0, -346, 0, 0, 0, -346, 0, 0, -346, 0, 0, 0, -346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -346, 0, -346, -346, -346, -346, 0, 0, 0, 0, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, 0, -346, -346, 0, -346, 0, 0, 0, -346, -346, 0, -346, -346, -346, -346, + 875, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, // State 803 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -342, 0, 0, 0, 0, 0, 0, -342, 0, -342, 0, 0, 0, -342, 0, 0, -342, 0, 0, 0, -342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -342, 0, -342, -342, -342, -342, 0, 0, 0, 0, 0, -342, -342, -342, -342, 0, -342, -342, -342, -342, 0, -342, -342, -342, -342, -342, -342, -342, -342, 0, 0, -342, -342, -342, -342, 0, -342, -342, -342, -342, -342, -342, -342, -342, -342, 0, 0, 0, -342, -342, 0, -342, 0, 0, 0, -342, -342, 0, -342, -342, -342, -342, // State 804 - -904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -346, 0, 0, 0, 0, 0, 0, -346, 0, -346, 0, 0, 0, -346, 0, 0, -346, 0, 0, 0, -346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -346, 0, -346, -346, -346, -346, 0, 0, 0, 0, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, 0, -346, -346, 0, -346, 0, 0, 0, -346, -346, 0, -346, -346, -346, -346, // State 805 - -921, 0, 0, 0, 0, 0, 0, -921, 0, -921, 0, 0, 0, -921, 0, 0, -921, 0, 0, 0, -921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -921, 0, -921, -921, -921, -921, 0, 0, 0, 0, 0, -921, -921, -921, -921, 0, -921, -921, -921, -921, 0, 885, 0, 0, -921, -921, -921, -921, -921, 0, 0, -921, -921, -921, -921, 0, -921, -921, -921, -921, -921, -921, -921, -921, -921, 0, 0, 0, -921, -921, 0, -921, 0, 0, 0, -921, -921, 0, -921, -921, -921, -921, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 806 - 0, 0, -242, -242, 0, -242, 0, -242, 0, -242, -242, 0, 0, -242, 0, -242, -242, 0, 0, -242, 0, -242, -242, 0, 0, -246, 0, 0, -242, -242, 0, -242, 0, -242, -242, -242, -242, 0, 0, -242, 0, 0, 0, 0, -242, 0, -242, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, -242, -242, 0, 0, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 807 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -924, 0, 0, 0, 0, 0, 0, -924, 0, -924, 0, 0, 0, -924, 0, 0, -924, 0, 0, 0, -924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -924, 0, -924, -924, -924, -924, 0, 0, 0, 0, 0, -924, -924, -924, -924, 0, -924, -924, -924, -924, 0, 887, 0, 0, -924, -924, -924, -924, -924, 0, 0, -924, -924, -924, -924, 0, -924, -924, -924, -924, -924, -924, -924, -924, -924, 0, 0, 0, -924, -924, 0, -924, 0, 0, 0, -924, -924, 0, -924, -924, -924, -924, // State 808 - 0, 0, -764, -764, 0, -764, 0, 0, 0, -764, 0, 0, 0, -764, 0, -764, -764, 0, 0, 0, 0, -764, -764, 0, 0, -766, 0, 0, -764, -764, 0, -764, 0, -764, -764, -764, -764, 0, 0, -764, 0, 0, 0, 0, 0, 0, -764, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, -764, -764, 0, 0, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -242, -242, 0, -242, 0, -242, 0, -242, -242, 0, 0, -242, 0, -242, -242, 0, 0, -242, 0, -242, -242, 0, 0, -246, 0, 0, -242, -242, 0, -242, 0, -242, -242, -242, -242, 0, 0, -242, 0, 0, 0, 0, -242, 0, -242, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, -242, -242, 0, 0, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 809 - 0, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, -350, 0, 0, -348, 0, 0, -348, 0, -348, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, -348, -348, 0, 0, 0, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 810 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -765, -765, 0, -765, 0, 0, 0, -765, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, 0, -765, -765, 0, 0, -767, 0, 0, -765, -765, 0, -765, 0, -765, -765, -765, -765, 0, 0, -765, 0, 0, 0, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 811 - 0, 0, -860, -860, 0, -860, 0, 0, 0, -860, 0, 0, 0, -860, 0, -860, -860, 0, 0, 0, 0, -860, -860, 0, 0, -862, 0, 0, -860, -860, 0, -860, 0, -860, -860, -860, -860, 0, 0, -860, 0, 0, 0, 0, 0, 0, -860, 0, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -860, 0, -860, -860, 0, 0, 0, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, -350, 0, 0, -348, 0, 0, -348, 0, -348, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, -348, -348, 0, 0, 0, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 812 - 0, 0, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 813 - 0, 0, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -859, -859, 0, -859, 0, 0, 0, -859, 0, 0, 0, -859, 0, -859, -859, 0, 0, 0, 0, -859, -859, 0, 0, -861, 0, 0, -859, -859, 0, -859, 0, -859, -859, -859, -859, 0, 0, -859, 0, 0, 0, 0, 0, 0, -859, 0, -859, -859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -859, 0, -859, -859, 0, 0, 0, -859, -859, 0, 0, 0, 0, 0, 0, 0, 0, 0, -859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 814 - 0, 0, 0, 0, 0, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -929, 0, 0, 0, 0, 0, 0, -929, 0, 0, 0, 0, 0, 0, 0, 0, 0, -929, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 815 - -941, 0, 0, 0, 0, 0, 0, -941, 0, -941, 0, 0, 0, -941, 0, 0, -941, 0, 0, 0, -941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -941, 0, -941, -941, -941, -941, 0, 0, 0, 0, 0, -941, -941, -941, -941, 0, -941, -941, -941, -941, 0, 0, 0, 0, -941, -941, -941, -941, -941, 0, 0, -941, -941, -941, -941, 0, -941, -941, -941, -941, -941, -941, -941, -941, -941, 0, 0, 0, -941, -941, 0, -941, 0, 0, 0, -941, -941, 0, -941, -941, -941, -941, + 0, 0, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 816 - 0, 0, -942, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, -944, 0, 0, -942, 0, 0, -942, 0, -942, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, -942, -942, 0, 0, 0, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 817 - 0, 0, 0, 0, 0, 0, 0, 0, 888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -944, 0, 0, 0, 0, 0, 0, -944, 0, -944, 0, 0, 0, -944, 0, 0, -944, 0, 0, 0, -944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -944, 0, -944, -944, -944, -944, 0, 0, 0, 0, 0, -944, -944, -944, -944, 0, -944, -944, -944, -944, 0, 0, 0, 0, -944, -944, -944, -944, -944, 0, 0, -944, -944, -944, -944, 0, -944, -944, -944, -944, -944, -944, -944, -944, -944, 0, 0, 0, -944, -944, 0, -944, 0, 0, 0, -944, -944, 0, -944, -944, -944, -944, // State 818 - 0, 0, 0, 0, 0, 0, 0, 0, 889, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -945, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, -947, 0, 0, -945, 0, 0, -945, 0, -945, -945, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -945, 0, -945, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -945, 0, -945, -945, 0, 0, 0, -945, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 819 - 0, 0, -196, -196, 0, -196, 0, -196, 0, -196, -196, 0, 0, -196, 0, -196, -196, 0, 0, -196, 0, -196, -196, 0, 0, -223, 0, 0, -196, -196, 0, -196, 0, -196, -196, -196, -196, 0, 0, -196, 0, 0, 0, 0, -196, 0, -196, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, -196, -196, 0, 0, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 820 - 0, 0, -190, -190, 0, -190, 0, -190, 0, -190, -190, 0, 0, -190, 0, -190, -190, 0, 0, -190, 0, -190, -190, 0, 0, -928, 0, 0, -190, -190, 0, -190, 0, -190, -190, -190, -190, 0, 0, -190, 0, 0, 0, 0, -190, 0, -190, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, -190, -190, 0, 0, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 891, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 821 - 0, 0, 0, 0, 0, 0, 0, 0, 893, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -196, -196, 0, -196, 0, -196, 0, -196, -196, 0, 0, -196, 0, -196, -196, 0, 0, -196, 0, -196, -196, 0, 0, -223, 0, 0, -196, -196, 0, -196, 0, -196, -196, -196, -196, 0, 0, -196, 0, 0, 0, 0, -196, 0, -196, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, -196, -196, 0, 0, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 822 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -190, -190, 0, -190, 0, -190, 0, -190, -190, 0, 0, -190, 0, -190, -190, 0, 0, -190, 0, -190, -190, 0, 0, -931, 0, 0, -190, -190, 0, -190, 0, -190, -190, -190, -190, 0, 0, -190, 0, 0, 0, 0, -190, 0, -190, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, -190, -190, 0, 0, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 823 - 0, 0, -200, -200, 0, -200, 0, -200, 0, -200, -200, 0, 0, -200, 0, -200, -200, 0, 0, -200, 0, -200, -200, 0, 0, -227, 0, 0, -200, -200, 0, -200, 0, -200, -200, -200, -200, 0, 0, -200, 0, 0, 0, 0, -200, 0, -200, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, -200, -200, 0, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 895, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 824 - 0, 0, 0, 0, 0, 0, 0, 0, 895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 825 - 0, 0, -186, -186, 0, -186, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -215, 0, 0, -186, -186, 0, -186, 0, -186, -186, -186, -186, 0, 0, -186, 0, 0, 0, 0, -186, 0, -186, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -200, -200, 0, -200, 0, -200, 0, -200, -200, 0, 0, -200, 0, -200, -200, 0, 0, -200, 0, -200, -200, 0, 0, -227, 0, 0, -200, -200, 0, -200, 0, -200, -200, -200, -200, 0, 0, -200, 0, 0, 0, 0, -200, 0, -200, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, -200, -200, 0, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 826 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 896, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 827 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -186, -186, 0, -186, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -215, 0, 0, -186, -186, 0, -186, 0, -186, -186, -186, -186, 0, 0, -186, 0, 0, 0, 0, -186, 0, -186, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 828 - 0, 0, -203, -203, 0, -203, 0, -203, 0, -203, -203, 0, 0, -203, 0, -203, -203, 0, 0, -203, 0, -203, -203, 0, 0, -230, 0, 0, -203, -203, 0, -203, 0, -203, -203, -203, -203, 0, 0, -203, 0, 0, 0, 0, -203, 0, -203, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, -203, -203, 0, 0, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 829 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 830 - 0, 0, -206, -206, 0, -206, 0, -206, 0, -206, -206, 0, 0, -206, 0, -206, -206, 0, 0, -206, 0, -206, -206, 0, 0, -233, 0, 0, -206, -206, 0, -206, 0, -206, -206, -206, -206, 0, 0, -206, 0, 0, 0, 0, -206, 0, -206, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, -206, -206, 0, 0, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -203, -203, 0, -203, 0, -203, 0, -203, -203, 0, 0, -203, 0, -203, -203, 0, 0, -203, 0, -203, -203, 0, 0, -230, 0, 0, -203, -203, 0, -203, 0, -203, -203, -203, -203, 0, 0, -203, 0, 0, 0, 0, -203, 0, -203, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, -203, -203, 0, 0, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 831 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 832 - -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 0, -197, 0, -197, -197, -197, -197, -197, 0, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 0, 0, 0, -197, -197, -197, -197, -197, -197, 0, -197, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, 0, -197, -197, 0, -197, 0, -197, -197, 0, 0, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -206, -206, 0, -206, 0, -206, 0, -206, -206, 0, 0, -206, 0, -206, -206, 0, 0, -206, 0, -206, -206, 0, 0, -233, 0, 0, -206, -206, 0, -206, 0, -206, -206, -206, -206, 0, 0, -206, 0, 0, 0, 0, -206, 0, -206, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, -206, -206, 0, 0, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 833 - -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 0, -191, 0, -191, -191, -191, -191, -191, 0, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 0, 0, 0, -191, -191, -191, -191, -191, -191, 0, -191, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, 0, -191, -191, 0, -191, 0, -191, -191, 0, 0, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -842, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -842, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 834 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 0, 0, 0, 0, 0, -695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 0, -197, 0, -197, -197, -197, -197, -197, 0, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 0, 0, 0, -197, -197, -197, -197, -197, -197, 0, -197, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, 0, -197, -197, 0, -197, 0, -197, -197, 0, 0, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 835 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, 0, 0, 0, 0, 0, -680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 0, -191, 0, -191, -191, -191, -191, -191, 0, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 0, 0, 0, -191, -191, -191, -191, -191, -191, 0, -191, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, 0, -191, -191, 0, -191, 0, -191, -191, 0, 0, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 836 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 905, 0, 0, 0, 0, 0, 0, 0, 0, 0, -708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 0, 0, 0, 0, 0, -696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 837 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -713, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 905, 0, 0, 0, 0, 0, 0, 0, 0, 0, -681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 838 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 907, 0, 0, 0, 0, 0, 0, 0, 0, 0, -720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 907, 0, 0, 0, 0, 0, 0, 0, 0, 0, -709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 839 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -710, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -714, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 840 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -383, 0, 0, -383, 0, 0, -383, 0, 0, 0, 0, 0, 0, -383, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 909, 0, 0, 0, 0, 0, 0, 0, 0, 0, -721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 841 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 842 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -380, 0, 0, -380, 0, 0, -380, 0, 0, 0, 0, 0, 0, -380, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -383, 0, 0, -383, 0, 0, -383, 0, 0, 0, 0, 0, 0, -383, 0, 0, 0, 0, // State 843 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -381, 0, 0, -381, 0, 0, -381, 0, 0, 0, 0, 0, 0, -381, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 844 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 283, 0, 0, 0, 0, 0, 0, 284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -380, 0, 0, -380, 0, 0, -380, 0, 0, 0, 0, 0, 0, -380, 0, 0, 0, 0, // State 845 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -381, 0, 0, -381, 0, 0, -381, 0, 0, 0, 0, 0, 0, -381, 0, 0, 0, 0, // State 846 - -272, 0, 0, 0, 0, 0, 0, -272, 0, -272, 0, 0, 0, -272, 0, 0, -272, 0, 0, 0, -272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -272, 0, -272, -272, -272, -272, 0, 0, 0, 0, 0, -272, -272, -272, -272, 0, -272, -272, -272, -272, 0, 0, 0, 0, -272, -272, -272, -272, -272, 0, 0, -272, -272, -272, -272, 0, -272, -272, -272, -272, -272, -272, -272, -272, -272, 0, 0, 0, -272, -272, 0, -272, 0, 0, 0, -272, -272, 0, -272, -272, -272, -272, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 283, 0, 0, 0, 0, 0, 0, 284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 847 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 848 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -272, 0, 0, 0, 0, 0, 0, -272, 0, -272, 0, 0, 0, -272, 0, 0, -272, 0, 0, 0, -272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -272, 0, -272, -272, -272, -272, 0, 0, 0, 0, 0, -272, -272, -272, -272, 0, -272, -272, -272, -272, 0, 0, 0, 0, -272, -272, -272, -272, -272, 0, 0, -272, -272, -272, -272, 0, -272, -272, -272, -272, -272, -272, -272, -272, -272, 0, 0, 0, -272, -272, 0, -272, 0, 0, 0, -272, -272, 0, -272, -272, -272, -272, // State 849 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 850 - -940, 0, 0, 0, 0, 0, 0, -940, 0, -940, 0, 0, 0, -940, 0, 0, -940, 0, 0, 0, -940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -940, 0, -940, -940, -940, -940, 0, 0, 0, 0, 0, -940, -940, -940, -940, 0, -940, -940, -940, -940, 0, 0, 0, 0, -940, -940, -940, -940, -940, 0, 0, -940, -940, -940, -940, 0, -940, -940, -940, -940, -940, -940, -940, -940, -940, 0, 0, 0, -940, -940, 0, -940, 0, 0, 0, -940, -940, 0, -940, -940, -940, -940, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 851 - -266, 0, 0, 0, 0, 0, 0, -266, 0, -266, 0, 0, 0, -266, 0, 0, -266, 0, 0, 0, -266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -266, 0, -266, -266, -266, -266, 0, 0, 0, 0, 0, -266, -266, -266, -266, 0, -266, -266, -266, -266, 0, 0, 0, 0, -266, -266, -266, -266, -266, 0, 0, -266, -266, -266, -266, 0, -266, -266, -266, -266, -266, -266, -266, -266, -266, 0, 0, 0, -266, -266, 0, -266, 0, 0, 0, -266, -266, 0, -266, -266, -266, -266, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 852 - -269, 0, 0, 0, 0, 0, 0, -269, 0, -269, 0, 0, 0, -269, 0, 0, -269, 0, 0, 0, -269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -269, 0, -269, -269, -269, -269, 0, 0, 0, 0, 0, -269, -269, -269, -269, 0, -269, -269, -269, -269, 0, 0, 0, 0, -269, -269, -269, -269, -269, 0, 0, -269, -269, -269, -269, 0, -269, -269, -269, -269, -269, -269, -269, -269, -269, 0, 0, 0, -269, -269, 0, -269, 0, 0, 0, -269, -269, 0, -269, -269, -269, -269, + -943, 0, 0, 0, 0, 0, 0, -943, 0, -943, 0, 0, 0, -943, 0, 0, -943, 0, 0, 0, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, -943, -943, -943, -943, 0, 0, 0, 0, 0, -943, -943, -943, -943, 0, -943, -943, -943, -943, 0, 0, 0, 0, -943, -943, -943, -943, -943, 0, 0, -943, -943, -943, -943, 0, -943, -943, -943, -943, -943, -943, -943, -943, -943, 0, 0, 0, -943, -943, 0, -943, 0, 0, 0, -943, -943, 0, -943, -943, -943, -943, // State 853 - 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -266, 0, 0, 0, 0, 0, 0, -266, 0, -266, 0, 0, 0, -266, 0, 0, -266, 0, 0, 0, -266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -266, 0, -266, -266, -266, -266, 0, 0, 0, 0, 0, -266, -266, -266, -266, 0, -266, -266, -266, -266, 0, 0, 0, 0, -266, -266, -266, -266, -266, 0, 0, -266, -266, -266, -266, 0, -266, -266, -266, -266, -266, -266, -266, -266, -266, 0, 0, 0, -266, -266, 0, -266, 0, 0, 0, -266, -266, 0, -266, -266, -266, -266, // State 854 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -269, 0, 0, 0, 0, 0, 0, -269, 0, -269, 0, 0, 0, -269, 0, 0, -269, 0, 0, 0, -269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -269, 0, -269, -269, -269, -269, 0, 0, 0, 0, 0, -269, -269, -269, -269, 0, -269, -269, -269, -269, 0, 0, 0, 0, -269, -269, -269, -269, -269, 0, 0, -269, -269, -269, -269, 0, -269, -269, -269, -269, -269, -269, -269, -269, -269, 0, 0, 0, -269, -269, 0, -269, 0, 0, 0, -269, -269, 0, -269, -269, -269, -269, // State 855 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 856 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 857 - -414, 0, 0, 0, 0, 0, 0, -414, 0, -414, 0, 0, 0, -414, 0, 0, -414, 0, 0, 0, -414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -414, 0, -414, -414, -414, -414, 0, 0, 0, 0, 0, -414, -414, -414, -414, 0, -414, -414, -414, -414, 0, 0, 0, 0, -414, -414, -414, -414, -414, 0, 0, -414, -414, -414, -414, 0, -414, -414, -414, -414, -414, -414, -414, -414, -414, 0, 0, 0, -414, -414, 0, -414, 0, 0, 0, -414, -414, 0, -414, -414, -414, -414, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 858 - 0, 0, 0, 0, 0, 0, 0, 0, -648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 859 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -746, 0, 0, 0, 0, 0, 0, -746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -414, 0, 0, 0, 0, 0, 0, -414, 0, -414, 0, 0, 0, -414, 0, 0, -414, 0, 0, 0, -414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -414, 0, -414, -414, -414, -414, 0, 0, 0, 0, 0, -414, -414, -414, -414, 0, -414, -414, -414, -414, 0, 0, 0, 0, -414, -414, -414, -414, -414, 0, 0, -414, -414, -414, -414, 0, -414, -414, -414, -414, -414, -414, -414, -414, -414, 0, 0, 0, -414, -414, 0, -414, 0, 0, 0, -414, -414, 0, -414, -414, -414, -414, // State 860 - 0, 0, 0, 0, 0, 0, 0, 0, -647, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 861 - 0, 0, 0, 0, 0, 0, 0, 0, -819, 0, 0, 0, 0, 0, 0, -819, 0, 0, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -747, 0, 0, 0, 0, 0, 0, -747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 862 - 0, 0, 0, 0, 0, 0, 0, 0, -457, 0, 0, 0, 0, 0, 0, -457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -648, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 863 - 0, 0, 0, 0, 0, 0, 0, 0, -336, 0, 0, 0, 0, 0, 0, -336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -820, 0, 0, 0, 0, 0, 0, -820, 0, 0, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 864 - 0, 0, 0, 0, 0, 0, 0, 0, 932, 0, 0, 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -457, 0, 0, 0, 0, 0, 0, -457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 865 - -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -336, 0, 0, 0, 0, 0, 0, -336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 866 - -434, 0, 0, 0, 0, 0, 0, -434, 0, -434, 0, 0, 0, -434, 0, 0, -434, 0, 0, 0, -434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -434, 0, -434, -434, -434, -434, 0, 0, 0, 0, 0, -434, -434, -434, -434, 0, -434, -434, -434, -434, 299, 933, 0, 0, -434, -434, -434, -434, -434, 0, 0, -434, -434, -434, -434, 0, -434, -434, -434, -434, -434, -434, -434, -434, -434, 0, 0, 0, -434, -434, 0, -434, 0, 0, 0, -434, -434, 0, -434, -434, -434, -434, + 0, 0, 0, 0, 0, 0, 0, 0, 934, 0, 0, 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 867 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 868 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -434, 0, 0, 0, 0, 0, 0, -434, 0, -434, 0, 0, 0, -434, 0, 0, -434, 0, 0, 0, -434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -434, 0, -434, -434, -434, -434, 0, 0, 0, 0, 0, -434, -434, -434, -434, 0, -434, -434, -434, -434, 299, 935, 0, 0, -434, -434, -434, -434, -434, 0, 0, -434, -434, -434, -434, 0, -434, -434, -434, -434, -434, -434, -434, -434, -434, 0, 0, 0, -434, -434, 0, -434, 0, 0, 0, -434, -434, 0, -434, -434, -434, -434, // State 869 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 870 - -858, 0, 0, 0, 0, 0, 0, -858, 0, -858, 0, 0, 0, -858, 0, 0, -858, 0, 0, 0, -858, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -858, 0, -858, -858, -858, -858, 0, 0, 0, 0, 0, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, 0, 0, -858, -858, -858, -858, 0, -858, -858, -858, -858, -858, -858, -858, -858, -858, 0, 0, 0, -858, -858, 0, -858, 0, 0, 0, -858, -858, 0, -858, -858, -858, -858, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 871 - 937, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 872 - -855, 0, 0, 0, 0, 0, 0, -855, 0, -855, 0, 0, 0, -855, 0, 0, -855, 0, 0, 0, -855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -855, 0, -855, -855, -855, -855, 0, 0, 0, 0, 0, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, 0, 0, -855, -855, -855, -855, 0, -855, -855, -855, -855, -855, -855, -855, -855, -855, 0, 0, 0, -855, -855, 0, -855, 0, 0, 0, -855, -855, 0, -855, -855, -855, -855, + -857, 0, 0, 0, 0, 0, 0, -857, 0, -857, 0, 0, 0, -857, 0, 0, -857, 0, 0, 0, -857, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -857, 0, -857, -857, -857, -857, 0, 0, 0, 0, 0, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, 0, 0, -857, -857, -857, -857, 0, -857, -857, -857, -857, -857, -857, -857, -857, -857, 0, 0, 0, -857, -857, 0, -857, 0, 0, 0, -857, -857, 0, -857, -857, -857, -857, // State 873 - -343, 0, 0, 0, 0, 0, 0, -343, 0, -343, 0, 0, 0, -343, 0, 0, -343, 0, 0, 0, -343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -343, 0, -343, -343, -343, -343, 0, 0, 0, 0, 0, -343, -343, -343, -343, 0, -343, -343, -343, -343, 0, -343, -343, -343, -343, -343, -343, -343, -343, 0, 0, -343, -343, -343, -343, 0, -343, -343, -343, -343, -343, -343, -343, -343, -343, 0, 0, 0, -343, -343, 0, -343, 0, 0, 0, -343, -343, 0, -343, -343, -343, -343, + 939, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, // State 874 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -854, 0, 0, 0, 0, 0, 0, -854, 0, -854, 0, 0, 0, -854, 0, 0, -854, 0, 0, 0, -854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -854, 0, -854, -854, -854, -854, 0, 0, 0, 0, 0, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, -854, 0, 0, -854, -854, -854, -854, 0, -854, -854, -854, -854, -854, -854, -854, -854, -854, 0, 0, 0, -854, -854, 0, -854, 0, 0, 0, -854, -854, 0, -854, -854, -854, -854, // State 875 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -343, 0, 0, 0, 0, 0, 0, -343, 0, -343, 0, 0, 0, -343, 0, 0, -343, 0, 0, 0, -343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -343, 0, -343, -343, -343, -343, 0, 0, 0, 0, 0, -343, -343, -343, -343, 0, -343, -343, -343, -343, 0, -343, -343, -343, -343, -343, -343, -343, -343, 0, 0, -343, -343, -343, -343, 0, -343, -343, -343, -343, -343, -343, -343, -343, -343, 0, 0, 0, -343, -343, 0, -343, 0, 0, 0, -343, -343, 0, -343, -343, -343, -343, // State 876 - -347, 0, 0, 0, 0, 0, 0, -347, 0, -347, 0, 0, 0, -347, 0, 0, -347, 0, 0, 0, -347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -347, 0, -347, -347, -347, -347, 0, 0, 0, 0, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, 0, -347, -347, 0, -347, 0, 0, 0, -347, -347, 0, -347, -347, -347, -347, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 877 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 878 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -347, 0, 0, 0, 0, 0, 0, -347, 0, -347, 0, 0, 0, -347, 0, 0, -347, 0, 0, 0, -347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -347, 0, -347, -347, -347, -347, 0, 0, 0, 0, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, 0, -347, -347, 0, -347, 0, 0, 0, -347, -347, 0, -347, -347, -347, -347, // State 879 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 880 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 881 - 0, 0, 0, 0, 0, 0, 0, -829, 0, -829, 0, 0, 0, -829, 0, 0, -829, 0, 0, 0, -829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -829, 0, -829, -829, -829, -829, 0, 0, 0, 0, 0, -829, -829, -829, -829, 0, -829, -829, -829, -829, 0, 0, 0, 0, -829, -829, -829, -829, -829, 0, 0, -829, -829, -829, -829, 0, -829, -829, -829, -829, -829, -829, -829, -829, -829, 0, 0, 0, -829, -829, 0, -829, 0, 0, 0, -829, -829, 0, -829, -829, -829, -829, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 882 - 942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 883 - -903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -830, 0, -830, 0, 0, 0, -830, 0, 0, -830, 0, 0, 0, -830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -830, 0, -830, -830, -830, -830, 0, 0, 0, 0, 0, -830, -830, -830, -830, 0, -830, -830, -830, -830, 0, 0, 0, 0, -830, -830, -830, -830, -830, 0, 0, -830, -830, -830, -830, 0, -830, -830, -830, -830, -830, -830, -830, -830, -830, 0, 0, 0, -830, -830, 0, -830, 0, 0, 0, -830, -830, 0, -830, -830, -830, -830, // State 884 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 885 - 0, 0, -241, -241, 0, -241, 0, -241, 0, -241, -241, 0, 0, -241, 0, -241, -241, 0, 0, -241, 0, -241, -241, 0, 0, -245, 0, 0, -241, -241, 0, -241, 0, -241, -241, -241, -241, 0, 0, -241, 0, 0, 0, 0, -241, 0, -241, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, -241, -241, 0, 0, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 886 - 0, 0, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 887 - 0, 0, -201, -201, 0, -201, 0, -201, 0, -201, -201, 0, 0, -201, 0, -201, -201, 0, 0, -201, 0, -201, -201, 0, 0, -228, 0, 0, -201, -201, 0, -201, 0, -201, -201, -201, -201, 0, 0, -201, 0, 0, 0, 0, -201, 0, -201, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, -201, -201, 0, 0, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -241, -241, 0, -241, 0, -241, 0, -241, -241, 0, 0, -241, 0, -241, -241, 0, 0, -241, 0, -241, -241, 0, 0, -245, 0, 0, -241, -241, 0, -241, 0, -241, -241, -241, -241, 0, 0, -241, 0, 0, 0, 0, -241, 0, -241, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, -241, -241, 0, 0, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 888 - 0, 0, -198, -198, 0, -198, 0, -198, 0, -198, -198, 0, 0, -198, 0, -198, -198, 0, 0, -198, 0, -198, -198, 0, 0, -225, 0, 0, -198, -198, 0, -198, 0, -198, -198, -198, -198, 0, 0, -198, 0, 0, 0, 0, -198, 0, -198, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, -198, -198, 0, 0, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 889 - 0, 0, -192, -192, 0, -192, 0, -192, 0, -192, -192, 0, 0, -192, 0, -192, -192, 0, 0, -192, 0, -192, -192, 0, 0, -219, 0, 0, -192, -192, 0, -192, 0, -192, -192, -192, -192, 0, 0, -192, 0, 0, 0, 0, -192, 0, -192, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, -192, -192, 0, 0, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -201, -201, 0, -201, 0, -201, 0, -201, -201, 0, 0, -201, 0, -201, -201, 0, 0, -201, 0, -201, -201, 0, 0, -228, 0, 0, -201, -201, 0, -201, 0, -201, -201, -201, -201, 0, 0, -201, 0, 0, 0, 0, -201, 0, -201, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, -201, -201, 0, 0, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 890 - 0, 0, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -198, -198, 0, -198, 0, -198, 0, -198, -198, 0, 0, -198, 0, -198, -198, 0, 0, -198, 0, -198, -198, 0, 0, -225, 0, 0, -198, -198, 0, -198, 0, -198, -198, -198, -198, 0, 0, -198, 0, 0, 0, 0, -198, 0, -198, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, -198, -198, 0, 0, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 891 - 0, 0, -189, -189, 0, -189, 0, -189, 0, -189, -189, 0, 0, -189, 0, -189, -189, 0, 0, -189, 0, -189, -189, 0, 0, -927, 0, 0, -189, -189, 0, -189, 0, -189, -189, -189, -189, 0, 0, -189, 0, 0, 0, 0, -189, 0, -189, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, -189, -189, 0, 0, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -192, -192, 0, -192, 0, -192, 0, -192, -192, 0, 0, -192, 0, -192, -192, 0, 0, -192, 0, -192, -192, 0, 0, -219, 0, 0, -192, -192, 0, -192, 0, -192, -192, -192, -192, 0, 0, -192, 0, 0, 0, 0, -192, 0, -192, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, -192, -192, 0, 0, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 892 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -550, 0, 0, 0, 0, 0, 0, -550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 893 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -930, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -189, -189, 0, -189, 0, -189, 0, -189, -189, 0, 0, -189, 0, -189, -189, 0, 0, -189, 0, -189, -189, 0, 0, -930, 0, 0, -189, -189, 0, -189, 0, -189, -189, -189, -189, 0, 0, -189, 0, 0, 0, 0, -189, 0, -189, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, -189, -189, 0, 0, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 894 - 0, 0, -202, -202, 0, -202, 0, -202, 0, -202, -202, 0, 0, -202, 0, -202, -202, 0, 0, -202, 0, -202, -202, 0, 0, -229, 0, 0, -202, -202, 0, -202, 0, -202, -202, -202, -202, 0, 0, -202, 0, 0, 0, 0, -202, 0, -202, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, -202, -202, 0, 0, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 895 - 0, 0, -188, -188, 0, -188, 0, -188, 0, -188, -188, 0, 0, -188, 0, -188, -188, 0, 0, -188, 0, -188, -188, 0, 0, -217, 0, 0, -188, -188, 0, -188, 0, -188, -188, -188, -188, 0, 0, -188, 0, 0, 0, 0, -188, 0, -188, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, -188, -188, 0, 0, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 896 - 0, 0, -205, -205, 0, -205, 0, -205, 0, -205, -205, 0, 0, -205, 0, -205, -205, 0, 0, -205, 0, -205, -205, 0, 0, -232, 0, 0, -205, -205, 0, -205, 0, -205, -205, -205, -205, 0, 0, -205, 0, 0, 0, 0, -205, 0, -205, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, -205, -205, 0, 0, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -202, -202, 0, -202, 0, -202, 0, -202, -202, 0, 0, -202, 0, -202, -202, 0, 0, -202, 0, -202, -202, 0, 0, -229, 0, 0, -202, -202, 0, -202, 0, -202, -202, -202, -202, 0, 0, -202, 0, 0, 0, 0, -202, 0, -202, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, -202, -202, 0, 0, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 897 - 0, 0, -207, -207, 0, -207, 0, -207, 0, -207, -207, 0, 0, -207, 0, -207, -207, 0, 0, -207, 0, -207, -207, 0, 0, -234, 0, 0, -207, -207, 0, -207, 0, -207, -207, -207, -207, 0, 0, -207, 0, 0, 0, 0, -207, 0, -207, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, -207, -207, 0, 0, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -188, -188, 0, -188, 0, -188, 0, -188, -188, 0, 0, -188, 0, -188, -188, 0, 0, -188, 0, -188, -188, 0, 0, -217, 0, 0, -188, -188, 0, -188, 0, -188, -188, -188, -188, 0, 0, -188, 0, 0, 0, 0, -188, 0, -188, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, -188, -188, 0, 0, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 898 - 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -205, -205, 0, -205, 0, -205, 0, -205, -205, 0, 0, -205, 0, -205, -205, 0, 0, -205, 0, -205, -205, 0, 0, -232, 0, 0, -205, -205, 0, -205, 0, -205, -205, -205, -205, 0, 0, -205, 0, 0, 0, 0, -205, 0, -205, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, -205, -205, 0, 0, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 899 - -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 0, -193, 0, -193, -193, -193, -193, -193, 0, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 0, 0, 0, -193, -193, -193, -193, -193, -193, 0, -193, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, 0, -193, -193, 0, -193, 0, -193, -193, 0, 0, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -207, -207, 0, -207, 0, -207, 0, -207, -207, 0, 0, -207, 0, -207, -207, 0, 0, -207, 0, -207, -207, 0, 0, -234, 0, 0, -207, -207, 0, -207, 0, -207, -207, -207, -207, 0, 0, -207, 0, 0, 0, 0, -207, 0, -207, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, -207, -207, 0, 0, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 900 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 957, 0, 0, 0, 0, 0, 0, 0, 0, 0, -686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 901 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 959, 0, 0, 0, 0, 0, 0, 0, 0, 0, -677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 0, -193, 0, -193, -193, -193, -193, -193, 0, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 0, 0, 0, -193, -193, -193, -193, -193, -193, 0, -193, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, 0, -193, -193, 0, -193, 0, -193, -193, 0, 0, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 902 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 959, 0, 0, 0, 0, 0, 0, 0, 0, 0, -687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 903 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 960, 0, 0, 0, 0, 0, 0, 0, 0, 0, -709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 961, 0, 0, 0, 0, 0, 0, 0, 0, 0, -678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 904 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 905 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, -699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 962, 0, 0, 0, 0, 0, 0, 0, 0, 0, -710, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 906 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -712, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -706, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 907 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -379, 0, 0, -379, 0, 0, -379, 0, 0, 0, 0, 0, 0, -379, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, -700, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 908 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -713, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 909 - -268, 0, 0, 0, 0, 0, 0, -268, 0, -268, 0, 0, 0, -268, 0, 0, -268, 0, 0, 0, -268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -268, 0, -268, -268, -268, -268, 0, 0, 0, 0, 0, -268, -268, -268, -268, 0, -268, -268, -268, -268, 0, 0, 0, 0, -268, -268, -268, -268, -268, 0, 0, -268, -268, -268, -268, 0, -268, -268, -268, -268, -268, -268, -268, -268, -268, 0, 0, 0, -268, -268, 0, -268, 0, 0, 0, -268, -268, 0, -268, -268, -268, -268, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -379, 0, 0, -379, 0, 0, -379, 0, 0, 0, 0, 0, 0, -379, 0, 0, 0, 0, // State 910 - -271, 0, 0, 0, 0, 0, 0, -271, 0, -271, 0, 0, 0, -271, 0, 0, -271, 0, 0, 0, -271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -271, 0, -271, -271, -271, -271, 0, 0, 0, 0, 0, -271, -271, -271, -271, 0, -271, -271, -271, -271, 0, 0, 0, 0, -271, -271, -271, -271, -271, 0, 0, -271, -271, -271, -271, 0, -271, -271, -271, -271, -271, -271, -271, -271, -271, 0, 0, 0, -271, -271, 0, -271, 0, 0, 0, -271, -271, 0, -271, -271, -271, -271, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 911 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -268, 0, 0, 0, 0, 0, 0, -268, 0, -268, 0, 0, 0, -268, 0, 0, -268, 0, 0, 0, -268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -268, 0, -268, -268, -268, -268, 0, 0, 0, 0, 0, -268, -268, -268, -268, 0, -268, -268, -268, -268, 0, 0, 0, 0, -268, -268, -268, -268, -268, 0, 0, -268, -268, -268, -268, 0, -268, -268, -268, -268, -268, -268, -268, -268, -268, 0, 0, 0, -268, -268, 0, -268, 0, 0, 0, -268, -268, 0, -268, -268, -268, -268, // State 912 - -416, 0, 0, 0, 0, 0, 0, -416, 0, -416, 0, 0, 0, -416, 0, 0, -416, 0, 0, 0, -416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -416, 0, -416, -416, -416, -416, 0, 0, 0, 0, 0, -416, -416, -416, -416, 0, -416, -416, -416, -416, 0, 0, 0, 0, -416, -416, -416, -416, -416, 0, 0, -416, -416, -416, -416, 0, -416, -416, -416, -416, -416, -416, -416, -416, -416, 0, 0, 0, -416, -416, 0, -416, 0, 0, 0, -416, -416, 0, -416, -416, -416, -416, + -271, 0, 0, 0, 0, 0, 0, -271, 0, -271, 0, 0, 0, -271, 0, 0, -271, 0, 0, 0, -271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -271, 0, -271, -271, -271, -271, 0, 0, 0, 0, 0, -271, -271, -271, -271, 0, -271, -271, -271, -271, 0, 0, 0, 0, -271, -271, -271, -271, -271, 0, 0, -271, -271, -271, -271, 0, -271, -271, -271, -271, -271, -271, -271, -271, -271, 0, 0, 0, -271, -271, 0, -271, 0, 0, 0, -271, -271, 0, -271, -271, -271, -271, // State 913 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 914 - -406, 0, 0, 0, 0, 0, 0, -406, 0, -406, 0, 0, 0, -406, 0, 0, -406, 0, 0, 0, -406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -406, 0, -406, -406, -406, -406, 0, 0, 0, 0, 0, -406, -406, -406, -406, 0, -406, -406, -406, -406, 0, 0, 0, 0, -406, -406, -406, -406, -406, 0, 0, -406, -406, -406, -406, 0, -406, -406, -406, -406, -406, -406, -406, -406, -406, 0, 0, 0, -406, -406, 0, -406, 0, 0, 0, -406, -406, 0, -406, -406, -406, -406, + -416, 0, 0, 0, 0, 0, 0, -416, 0, -416, 0, 0, 0, -416, 0, 0, -416, 0, 0, 0, -416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -416, 0, -416, -416, -416, -416, 0, 0, 0, 0, 0, -416, -416, -416, -416, 0, -416, -416, -416, -416, 0, 0, 0, 0, -416, -416, -416, -416, -416, 0, 0, -416, -416, -416, -416, 0, -416, -416, -416, -416, -416, -416, -416, -416, -416, 0, 0, 0, -416, -416, 0, -416, 0, 0, 0, -416, -416, 0, -416, -416, -416, -416, // State 915 - -265, 0, 0, 0, 0, 0, 0, -265, 0, -265, 0, 0, 0, -265, 0, 0, -265, 0, 0, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -265, 0, -265, -265, -265, -265, 0, 0, 0, 0, 0, -265, -265, -265, -265, 0, -265, -265, -265, -265, 0, 0, 0, 0, -265, -265, -265, -265, -265, 0, 0, -265, -265, -265, -265, 0, -265, -265, -265, -265, -265, -265, -265, -265, -265, 0, 0, 0, -265, -265, 0, -265, 0, 0, 0, -265, -265, 0, -265, -265, -265, -265, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 916 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -406, 0, 0, 0, 0, 0, 0, -406, 0, -406, 0, 0, 0, -406, 0, 0, -406, 0, 0, 0, -406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -406, 0, -406, -406, -406, -406, 0, 0, 0, 0, 0, -406, -406, -406, -406, 0, -406, -406, -406, -406, 0, 0, 0, 0, -406, -406, -406, -406, -406, 0, 0, -406, -406, -406, -406, 0, -406, -406, -406, -406, -406, -406, -406, -406, -406, 0, 0, 0, -406, -406, 0, -406, 0, 0, 0, -406, -406, 0, -406, -406, -406, -406, // State 917 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -265, 0, 0, 0, 0, 0, 0, -265, 0, -265, 0, 0, 0, -265, 0, 0, -265, 0, 0, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -265, 0, -265, -265, -265, -265, 0, 0, 0, 0, 0, -265, -265, -265, -265, 0, -265, -265, -265, -265, 0, 0, 0, 0, -265, -265, -265, -265, -265, 0, 0, -265, -265, -265, -265, 0, -265, -265, -265, -265, -265, -265, -265, -265, -265, 0, 0, 0, -265, -265, 0, -265, 0, 0, 0, -265, -265, 0, -265, -265, -265, -265, // State 918 - 0, 0, 0, 0, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 919 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 920 - -413, 0, 0, 0, 0, 0, 0, -413, 0, -413, 0, 0, 0, -413, 0, 0, -413, 0, 0, 0, -413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -413, 0, -413, -413, -413, -413, 0, 0, 0, 0, 0, -413, -413, -413, -413, 0, -413, -413, -413, -413, 0, 0, 0, 0, -413, -413, -413, -413, -413, 0, 0, -413, -413, -413, -413, 0, -413, -413, -413, -413, -413, -413, -413, -413, -413, 0, 0, 0, -413, -413, 0, -413, 0, 0, 0, -413, -413, 0, -413, -413, -413, -413, + 0, 0, 0, 0, 0, 0, 0, -912, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -912, 0, 0, 0, 0, 0, 0, -912, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 921 - 0, 0, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 922 - 0, 0, 0, 0, 0, 0, 0, 0, -629, 0, 0, 0, 0, 0, 0, 973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -413, 0, 0, 0, 0, 0, 0, -413, 0, -413, 0, 0, 0, -413, 0, 0, -413, 0, 0, 0, -413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -413, 0, -413, -413, -413, -413, 0, 0, 0, 0, 0, -413, -413, -413, -413, 0, -413, -413, -413, -413, 0, 0, 0, 0, -413, -413, -413, -413, -413, 0, 0, -413, -413, -413, -413, 0, -413, -413, -413, -413, -413, -413, -413, -413, -413, 0, 0, 0, -413, -413, 0, -413, 0, 0, 0, -413, -413, 0, -413, -413, -413, -413, // State 923 - 0, 0, 0, 0, 0, 0, 0, 0, -543, 0, 0, 0, 0, 0, 0, -543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 924 - 0, 0, 0, 0, 0, 0, 0, 0, -563, 0, 0, 0, 0, 0, 0, -563, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -630, 0, 0, 0, 0, 0, 0, 975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 925 - 0, 0, 0, 0, 0, 0, 0, 0, -646, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -544, 0, 0, 0, 0, 0, 0, -544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 926 - 0, 0, 0, 0, 0, 0, 0, 0, -641, 0, 0, 0, 0, 0, 0, 980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -564, 0, 0, 0, 0, 0, 0, -564, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 927 - 0, 0, 0, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -647, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 928 - -400, 0, 0, 0, 0, 0, 0, -400, 0, -400, 0, 0, 0, -400, 0, 0, -400, 0, 0, 0, -400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -400, 0, -400, -400, -400, -400, 0, 0, 0, 0, 0, -400, -400, -400, -400, 0, -400, -400, -400, -400, 0, 982, 0, 0, -400, -400, -400, -400, -400, 0, 0, -400, -400, -400, -400, 0, -400, -400, -400, -400, -400, -400, -400, -400, -400, 0, 0, 0, -400, -400, 0, -400, 0, 0, 0, -400, -400, 0, -400, -400, -400, -400, + 0, 0, 0, 0, 0, 0, 0, 0, -642, 0, 0, 0, 0, 0, 0, 982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 929 - -534, 0, 0, 0, 0, 0, 0, 0, -534, 0, 0, 0, 0, 0, 0, -534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 930 - -537, 0, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -400, 0, 0, 0, 0, 0, 0, -400, 0, -400, 0, 0, 0, -400, 0, 0, -400, 0, 0, 0, -400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -400, 0, -400, -400, -400, -400, 0, 0, 0, 0, 0, -400, -400, -400, -400, 0, -400, -400, -400, -400, 0, 984, 0, 0, -400, -400, -400, -400, -400, 0, 0, -400, -400, -400, -400, 0, -400, -400, -400, -400, -400, -400, -400, -400, -400, 0, 0, 0, -400, -400, 0, -400, 0, 0, 0, -400, -400, 0, -400, -400, -400, -400, // State 931 - -441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -535, 0, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 932 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -538, 0, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 933 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 934 - -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 935 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 936 - -856, 0, 0, 0, 0, 0, 0, -856, 0, -856, 0, 0, 0, -856, 0, 0, -856, 0, 0, 0, -856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -856, 0, -856, -856, -856, -856, 0, 0, 0, 0, 0, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, 0, 0, -856, -856, -856, -856, 0, -856, -856, -856, -856, -856, -856, -856, -856, -856, 0, 0, 0, -856, -856, 0, -856, 0, 0, 0, -856, -856, 0, -856, -856, -856, -856, + -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 937 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 938 - -340, 0, 0, 0, 0, 0, 0, -340, 0, -340, 0, 0, 0, -340, 0, 0, -340, 0, 0, 0, -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -340, 0, -340, -340, -340, -340, 0, 0, 0, 0, 0, -340, -340, -340, -340, 0, -340, -340, -340, -340, 0, -340, -340, -340, -340, -340, -340, -340, -340, 0, 0, -340, -340, -340, -340, 0, -340, -340, -340, -340, -340, -340, -340, -340, -340, 0, 0, 0, -340, -340, 0, -340, 0, 0, 0, -340, -340, 0, -340, -340, -340, -340, + -855, 0, 0, 0, 0, 0, 0, -855, 0, -855, 0, 0, 0, -855, 0, 0, -855, 0, 0, 0, -855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -855, 0, -855, -855, -855, -855, 0, 0, 0, 0, 0, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, 0, 0, -855, -855, -855, -855, 0, -855, -855, -855, -855, -855, -855, -855, -855, -855, 0, 0, 0, -855, -855, 0, -855, 0, 0, 0, -855, -855, 0, -855, -855, -855, -855, // State 939 - -893, 0, 0, 0, 0, 0, 0, -893, 0, -893, 0, 0, 0, -893, 0, 0, -893, 0, 0, 0, -893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -893, 0, -893, -893, -893, -893, 0, 0, 0, 0, 0, -893, -893, -893, -893, 0, -893, -893, -893, -893, 0, 0, 0, 0, -893, -893, -893, -893, -893, 0, 0, -893, -893, -893, -893, 0, -893, -893, -893, -893, -893, -893, -893, -893, -893, 0, 0, 0, -893, -893, 0, -893, 0, 0, 0, -893, -893, 0, -893, -893, -893, -893, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 940 - 1016, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -340, 0, 0, 0, 0, 0, 0, -340, 0, -340, 0, 0, 0, -340, 0, 0, -340, 0, 0, 0, -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -340, 0, -340, -340, -340, -340, 0, 0, 0, 0, 0, -340, -340, -340, -340, 0, -340, -340, -340, -340, 0, -340, -340, -340, -340, -340, -340, -340, -340, 0, 0, -340, -340, -340, -340, 0, -340, -340, -340, -340, -340, -340, -340, -340, -340, 0, 0, 0, -340, -340, 0, -340, 0, 0, 0, -340, -340, 0, -340, -340, -340, -340, // State 941 - 0, 0, 0, 0, 0, 0, 0, -827, 0, -827, 0, 0, 0, -827, 0, 0, -827, 0, 0, 0, -827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -827, 0, -827, -827, -827, -827, 0, 0, 0, 0, 0, -827, -827, -827, -827, 0, -827, -827, -827, -827, 0, 0, 0, 0, -827, -827, -827, -827, -827, 0, 0, -827, -827, -827, -827, 0, -827, -827, -827, -827, -827, -827, -827, -827, -827, 0, 0, 0, -827, -827, 0, -827, 0, 0, 0, -827, -827, 0, -827, -827, -827, -827, + -892, 0, 0, 0, 0, 0, 0, -892, 0, -892, 0, 0, 0, -892, 0, 0, -892, 0, 0, 0, -892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -892, 0, -892, -892, -892, -892, 0, 0, 0, 0, 0, -892, -892, -892, -892, 0, -892, -892, -892, -892, 0, 0, 0, 0, -892, -892, -892, -892, -892, 0, 0, -892, -892, -892, -892, 0, -892, -892, -892, -892, -892, -892, -892, -892, -892, 0, 0, 0, -892, -892, 0, -892, 0, 0, 0, -892, -892, 0, -892, -892, -892, -892, // State 942 - 1018, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, + 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1018, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 943 - 0, 0, 0, 0, 0, 0, 0, -830, 0, -830, 0, 0, 0, -830, 0, 0, -830, 0, 0, 0, -830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -830, 0, -830, -830, -830, -830, 0, 0, 0, 0, 0, -830, -830, -830, -830, 0, -830, -830, -830, -830, 0, 0, 0, 0, -830, -830, -830, -830, -830, 0, 0, -830, -830, -830, -830, 0, -830, -830, -830, -830, -830, -830, -830, -830, -830, 0, 0, 0, -830, -830, 0, -830, 0, 0, 0, -830, -830, 0, -830, -830, -830, -830, + 0, 0, 0, 0, 0, 0, 0, -828, 0, -828, 0, 0, 0, -828, 0, 0, -828, 0, 0, 0, -828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -828, 0, -828, -828, -828, -828, 0, 0, 0, 0, 0, -828, -828, -828, -828, 0, -828, -828, -828, -828, 0, 0, 0, 0, -828, -828, -828, -828, -828, 0, 0, -828, -828, -828, -828, 0, -828, -828, -828, -828, -828, -828, -828, -828, -828, 0, 0, 0, -828, -828, 0, -828, 0, 0, 0, -828, -828, 0, -828, -828, -828, -828, // State 944 - 1020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1019, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, // State 945 - -859, 0, 0, 0, 0, 0, 0, -859, 0, -859, 0, 0, 0, -859, 0, 0, -859, 0, 0, 0, -859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -859, 0, -859, -859, -859, -859, 0, 0, 0, 0, 0, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, 0, 0, -859, -859, -859, -859, 0, -859, -859, -859, -859, -859, -859, -859, -859, -859, 0, 0, 0, -859, -859, 0, -859, 0, 0, 0, -859, -859, 0, -859, -859, -859, -859, + 0, 0, 0, 0, 0, 0, 0, -831, 0, -831, 0, 0, 0, -831, 0, 0, -831, 0, 0, 0, -831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -831, 0, -831, -831, -831, -831, 0, 0, 0, 0, 0, -831, -831, -831, -831, 0, -831, -831, -831, -831, 0, 0, 0, 0, -831, -831, -831, -831, -831, 0, 0, -831, -831, -831, -831, 0, -831, -831, -831, -831, -831, -831, -831, -831, -831, 0, 0, 0, -831, -831, 0, -831, 0, 0, 0, -831, -831, 0, -831, -831, -831, -831, // State 946 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, -869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 947 - 0, 0, -194, -194, 0, -194, 0, -194, 0, -194, -194, 0, 0, -194, 0, -194, -194, 0, 0, -194, 0, -194, -194, 0, 0, -221, 0, 0, -194, -194, 0, -194, 0, -194, -194, -194, -194, 0, 0, -194, 0, 0, 0, 0, -194, 0, -194, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, -194, -194, 0, 0, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -858, 0, 0, 0, 0, 0, 0, -858, 0, -858, 0, 0, 0, -858, 0, 0, -858, 0, 0, 0, -858, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -858, 0, -858, -858, -858, -858, 0, 0, 0, 0, 0, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, 0, 0, -858, -858, -858, -858, 0, -858, -858, -858, -858, -858, -858, -858, -858, -858, 0, 0, 0, -858, -858, 0, -858, 0, 0, 0, -858, -858, 0, -858, -858, -858, -858, // State 948 - 0, 0, 0, 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, -868, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 949 - 0, 0, -195, -195, 0, -195, 0, -195, 0, -195, -195, 0, 0, -195, 0, -195, -195, 0, 0, -195, 0, -195, -195, 0, 0, -222, 0, 0, -195, -195, 0, -195, 0, -195, -195, -195, -195, 0, 0, -195, 0, 0, 0, 0, -195, 0, -195, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, -195, -195, 0, 0, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -194, -194, 0, -194, 0, -194, 0, -194, -194, 0, 0, -194, 0, -194, -194, 0, 0, -194, 0, -194, -194, 0, 0, -221, 0, 0, -194, -194, 0, -194, 0, -194, -194, -194, -194, 0, 0, -194, 0, 0, 0, 0, -194, 0, -194, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, -194, -194, 0, 0, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 950 - 0, 0, 0, 0, 0, 0, 0, 0, 1025, 0, 0, 0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 951 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -195, -195, 0, -195, 0, -195, 0, -195, -195, 0, 0, -195, 0, -195, -195, 0, 0, -195, 0, -195, -195, 0, 0, -222, 0, 0, -195, -195, 0, -195, 0, -195, -195, -195, -195, 0, 0, -195, 0, 0, 0, 0, -195, 0, -195, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, -195, -195, 0, 0, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 952 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1026, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 953 - 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 954 - 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 955 - 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 956 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 957 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, -683, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 958 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 959 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -706, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1028, 0, 0, 0, 0, 0, 0, 0, 0, 0, -684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 960 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, -700, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 961 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, -696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 962 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1032, 0, 0, 0, 0, 0, 0, 0, 0, 0, -681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, -701, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 963 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, -697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 964 - -408, 0, 0, 0, 0, 0, 0, -408, 0, -408, 0, 0, 0, -408, 0, 0, -408, 0, 0, 0, -408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -408, 0, -408, -408, -408, -408, 0, 0, 0, 0, 0, -408, -408, -408, -408, 0, -408, -408, -408, -408, 0, 0, 0, 0, -408, -408, -408, -408, -408, 0, 0, -408, -408, -408, -408, 0, -408, -408, -408, -408, -408, -408, -408, -408, -408, 0, 0, 0, -408, -408, 0, -408, 0, 0, 0, -408, -408, 0, -408, -408, -408, -408, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 0, 0, 0, 0, 0, 0, 0, 0, 0, -682, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 965 - -267, 0, 0, 0, 0, 0, 0, -267, 0, -267, 0, 0, 0, -267, 0, 0, -267, 0, 0, 0, -267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -267, 0, -267, -267, -267, -267, 0, 0, 0, 0, 0, -267, -267, -267, -267, 0, -267, -267, -267, -267, 0, 0, 0, 0, -267, -267, -267, -267, -267, 0, 0, -267, -267, -267, -267, 0, -267, -267, -267, -267, -267, -267, -267, -267, -267, 0, 0, 0, -267, -267, 0, -267, 0, 0, 0, -267, -267, 0, -267, -267, -267, -267, - // State 966 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 966 + -408, 0, 0, 0, 0, 0, 0, -408, 0, -408, 0, 0, 0, -408, 0, 0, -408, 0, 0, 0, -408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -408, 0, -408, -408, -408, -408, 0, 0, 0, 0, 0, -408, -408, -408, -408, 0, -408, -408, -408, -408, 0, 0, 0, 0, -408, -408, -408, -408, -408, 0, 0, -408, -408, -408, -408, 0, -408, -408, -408, -408, -408, -408, -408, -408, -408, 0, 0, 0, -408, -408, 0, -408, 0, 0, 0, -408, -408, 0, -408, -408, -408, -408, // State 967 - -415, 0, 0, 0, 0, 0, 0, -415, 0, -415, 0, 0, 0, -415, 0, 0, -415, 0, 0, 0, -415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -415, 0, -415, -415, -415, -415, 0, 0, 0, 0, 0, -415, -415, -415, -415, 0, -415, -415, -415, -415, 0, 0, 0, 0, -415, -415, -415, -415, -415, 0, 0, -415, -415, -415, -415, 0, -415, -415, -415, -415, -415, -415, -415, -415, -415, 0, 0, 0, -415, -415, 0, -415, 0, 0, 0, -415, -415, 0, -415, -415, -415, -415, + -267, 0, 0, 0, 0, 0, 0, -267, 0, -267, 0, 0, 0, -267, 0, 0, -267, 0, 0, 0, -267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -267, 0, -267, -267, -267, -267, 0, 0, 0, 0, 0, -267, -267, -267, -267, 0, -267, -267, -267, -267, 0, 0, 0, 0, -267, -267, -267, -267, -267, 0, 0, -267, -267, -267, -267, 0, -267, -267, -267, -267, -267, -267, -267, -267, -267, 0, 0, 0, -267, -267, 0, -267, 0, 0, 0, -267, -267, 0, -267, -267, -267, -267, // State 968 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 969 - -405, 0, 0, 0, 0, 0, 0, -405, 0, -405, 0, 0, 0, -405, 0, 0, -405, 0, 0, 0, -405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -405, 0, -405, -405, -405, -405, 0, 0, 0, 0, 0, -405, -405, -405, -405, 0, -405, -405, -405, -405, 0, 0, 0, 0, -405, -405, -405, -405, -405, 0, 0, -405, -405, -405, -405, 0, -405, -405, -405, -405, -405, -405, -405, -405, -405, 0, 0, 0, -405, -405, 0, -405, 0, 0, 0, -405, -405, 0, -405, -405, -405, -405, + -415, 0, 0, 0, 0, 0, 0, -415, 0, -415, 0, 0, 0, -415, 0, 0, -415, 0, 0, 0, -415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -415, 0, -415, -415, -415, -415, 0, 0, 0, 0, 0, -415, -415, -415, -415, 0, -415, -415, -415, -415, 0, 0, 0, 0, -415, -415, -415, -415, -415, 0, 0, -415, -415, -415, -415, 0, -415, -415, -415, -415, -415, -415, -415, -415, -415, 0, 0, 0, -415, -415, 0, -415, 0, 0, 0, -415, -415, 0, -415, -415, -415, -415, // State 970 - -398, 0, 0, 0, 0, 0, 0, -398, 0, -398, 0, 0, 0, -398, 0, 0, -398, 0, 0, 0, -398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -398, 0, -398, -398, -398, -398, 0, 0, 0, 0, 0, -398, -398, -398, -398, 0, -398, -398, -398, -398, 0, 1037, 0, 0, -398, -398, -398, -398, -398, 0, 0, -398, -398, -398, -398, 0, -398, -398, -398, -398, -398, -398, -398, -398, -398, 0, 0, 0, -398, -398, 0, -398, 0, 0, 0, -398, -398, 0, -398, -398, -398, -398, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 971 - -410, 0, 0, 0, 0, 0, 0, -410, 0, -410, 0, 0, 0, -410, 0, 0, -410, 0, 0, 0, -410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -410, 0, -410, -410, -410, -410, 0, 0, 0, 0, 0, -410, -410, -410, -410, 0, -410, -410, -410, -410, 0, 0, 0, 0, -410, -410, -410, -410, -410, 0, 0, -410, -410, -410, -410, 0, -410, -410, -410, -410, -410, -410, -410, -410, -410, 0, 0, 0, -410, -410, 0, -410, 0, 0, 0, -410, -410, 0, -410, -410, -410, -410, + -405, 0, 0, 0, 0, 0, 0, -405, 0, -405, 0, 0, 0, -405, 0, 0, -405, 0, 0, 0, -405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -405, 0, -405, -405, -405, -405, 0, 0, 0, 0, 0, -405, -405, -405, -405, 0, -405, -405, -405, -405, 0, 0, 0, 0, -405, -405, -405, -405, -405, 0, 0, -405, -405, -405, -405, 0, -405, -405, -405, -405, -405, -405, -405, -405, -405, 0, 0, 0, -405, -405, 0, -405, 0, 0, 0, -405, -405, 0, -405, -405, -405, -405, // State 972 - 0, 0, 0, 0, 0, 0, 0, 0, -626, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -398, 0, 0, 0, 0, 0, 0, -398, 0, -398, 0, 0, 0, -398, 0, 0, -398, 0, 0, 0, -398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -398, 0, -398, -398, -398, -398, 0, 0, 0, 0, 0, -398, -398, -398, -398, 0, -398, -398, -398, -398, 0, 1038, 0, 0, -398, -398, -398, -398, -398, 0, 0, -398, -398, -398, -398, 0, -398, -398, -398, -398, -398, -398, -398, -398, -398, 0, 0, 0, -398, -398, 0, -398, 0, 0, 0, -398, -398, 0, -398, -398, -398, -398, // State 973 - 0, 0, 0, 0, 0, 0, 0, 0, -620, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -410, 0, 0, 0, 0, 0, 0, -410, 0, -410, 0, 0, 0, -410, 0, 0, -410, 0, 0, 0, -410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -410, 0, -410, -410, -410, -410, 0, 0, 0, 0, 0, -410, -410, -410, -410, 0, -410, -410, -410, -410, 0, 0, 0, 0, -410, -410, -410, -410, -410, 0, 0, -410, -410, -410, -410, 0, -410, -410, -410, -410, -410, -410, -410, -410, -410, 0, 0, 0, -410, -410, 0, -410, 0, 0, 0, -410, -410, 0, -410, -410, -410, -410, // State 974 - 0, 0, 0, 0, 0, 0, 0, 0, -625, 0, 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 975 - 0, 0, 0, 0, 0, 0, 0, 0, -643, 0, 0, 0, 0, 0, 0, 1042, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -621, 0, 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 976 - 0, 0, 0, 0, 0, 0, 0, 0, -19, 0, 0, 0, 0, 0, 0, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -626, 0, 0, 0, 0, 0, 0, 358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 977 - 0, 0, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -644, 0, 0, 0, 0, 0, 0, 1043, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 978 - 0, 0, 0, 0, 0, 0, 0, 0, -640, 0, 0, 0, 0, 0, 0, 1044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -19, 0, 0, 0, 0, 0, 0, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 979 - 0, 0, 0, 0, 0, 0, 0, 0, -633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -819, 0, 0, 0, 0, 0, 0, -819, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 980 - 0, 0, 0, 0, 0, 0, 0, 0, -335, 0, 0, 0, 0, 0, 0, -335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -641, 0, 0, 0, 0, 0, 0, 1045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 981 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 982 - -440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -335, 0, 0, 0, 0, 0, 0, -335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 983 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 984 - -431, 0, 0, 0, 0, 0, 0, -431, 0, -431, 0, 0, 0, -431, 0, 0, -431, 0, 0, 0, -431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -431, 0, -431, -431, -431, -431, 0, 0, 0, 0, 0, -431, -431, -431, -431, 0, -431, -431, -431, -431, 0, 0, 0, 0, -431, -431, -431, -431, -431, 0, 0, -431, -431, -431, -431, 0, -431, -431, -431, -431, -431, -431, -431, -431, -431, 0, 0, 0, -431, -431, 0, -431, 0, 0, 0, -431, -431, 0, -431, -431, -431, -431, + -440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 985 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 986 - -498, 0, 0, 0, 0, 0, 0, -498, 0, -498, 0, 0, 0, -498, 0, 0, -498, 0, 0, 0, -498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -498, 0, -498, -498, -498, -498, 0, 0, 0, 0, 0, -498, -498, -498, -498, 0, -498, -498, -498, -498, 0, 0, 0, 0, -498, -498, -498, -498, -498, 0, 0, -498, -498, -498, -498, 0, -498, -498, -498, -498, -498, -498, -498, -498, -498, 0, 0, 0, -498, -498, 0, -498, 0, 0, 0, -498, -498, 0, -498, -498, -498, -498, + -431, 0, 0, 0, 0, 0, 0, -431, 0, -431, 0, 0, 0, -431, 0, 0, -431, 0, 0, 0, -431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -431, 0, -431, -431, -431, -431, 0, 0, 0, 0, 0, -431, -431, -431, -431, 0, -431, -431, -431, -431, 0, 0, 0, 0, -431, -431, -431, -431, -431, 0, 0, -431, -431, -431, -431, 0, -431, -431, -431, -431, -431, -431, -431, -431, -431, 0, 0, 0, -431, -431, 0, -431, 0, 0, 0, -431, -431, 0, -431, -431, -431, -431, // State 987 - 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 988 - 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -499, 0, 0, 0, 0, 0, 0, -499, 0, -499, 0, 0, 0, -499, 0, 0, -499, 0, 0, 0, -499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -499, 0, -499, -499, -499, -499, 0, 0, 0, 0, 0, -499, -499, -499, -499, 0, -499, -499, -499, -499, 0, 0, 0, 0, -499, -499, -499, -499, -499, 0, 0, -499, -499, -499, -499, 0, -499, -499, -499, -499, -499, -499, -499, -499, -499, 0, 0, 0, -499, -499, 0, -499, 0, 0, 0, -499, -499, 0, -499, -499, -499, -499, // State 989 - 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 990 - 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 991 - 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 992 - 0, 0, 0, 0, 0, 0, 0, -495, -264, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -495, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 993 - 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 362, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 994 - 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -496, -264, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -496, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 995 - 0, 0, 0, 0, 0, 0, 0, 0, -521, 0, 0, 0, 0, -521, 0, -521, -521, 0, 0, 0, 0, 0, 0, 0, 0, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -521, 0, 0, 0, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -521, 0, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 996 - 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, -522, 0, -522, -522, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 997 - 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, -522, 0, -522, -522, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 998 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 367, 0, 0, 0, 0, 0, 0, 0, 0, 0, -763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, -523, 0, -523, -523, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 999 - 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -751, 0, 0, 0, 0, 0, 0, -751, 0, 0, 0, 0, 0, 0, 0, 0, 0, -751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -751, 0, 0, 0, 367, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1000 - 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1001 - 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, + 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1002 - 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1003 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 0, 0, 0, -762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 371, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1004 - 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, -763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1005 - 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1006 - 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1007 - 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1008 - -501, 0, 0, 0, 0, 0, 0, -501, 0, -501, 0, 0, 0, -501, 0, 0, -501, 0, 0, 0, -501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -501, 0, -501, -501, -501, -501, 0, 0, 0, 0, 0, -501, -501, -501, -501, 0, -501, -501, -501, -501, 0, 0, 0, 0, -501, -501, -501, -501, -501, 0, 0, -501, -501, -501, -501, 0, -501, -501, -501, -501, -501, -501, -501, -501, -501, 0, 0, 0, -501, -501, 0, -501, 0, 0, 0, -501, -501, 0, -501, -501, -501, -501, + 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1009 - -886, 0, 0, 0, 0, 0, 0, -886, 0, -886, 0, 0, 0, -886, 0, 0, -886, 0, 0, 0, -886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -886, 0, -886, -886, -886, -886, 0, 0, 0, 0, 0, -886, -886, -886, -886, 0, -886, -886, -886, -886, 0, 0, 0, 1071, -886, -886, -886, -886, -886, 0, 0, -886, -886, -886, -886, 0, -886, -886, -886, -886, -886, -886, -886, -886, -886, 0, 0, 0, -886, -886, 0, -886, 0, 0, 0, -886, -886, 0, -886, -886, -886, -886, + -502, 0, 0, 0, 0, 0, 0, -502, 0, -502, 0, 0, 0, -502, 0, 0, -502, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, 0, -502, -502, -502, -502, 0, 0, 0, 0, 0, -502, -502, -502, -502, 0, -502, -502, -502, -502, 0, 0, 0, 0, -502, -502, -502, -502, -502, 0, 0, -502, -502, -502, -502, 0, -502, -502, -502, -502, -502, -502, -502, -502, -502, 0, 0, 0, -502, -502, 0, -502, 0, 0, 0, -502, -502, 0, -502, -502, -502, -502, // State 1010 - -887, 0, 0, 0, 0, 0, 0, -887, 0, -887, 0, 0, 0, -887, 0, 0, -887, 0, 0, 0, -887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -887, 0, -887, -887, -887, -887, 0, 0, 0, 0, 0, -887, -887, -887, -887, 0, -887, -887, -887, -887, 0, 0, 0, 0, -887, -887, -887, -887, -887, 0, 0, -887, -887, -887, -887, 0, -887, -887, -887, -887, -887, -887, -887, -887, -887, 0, 0, 0, -887, -887, 0, -887, 0, 0, 0, -887, -887, 0, -887, -887, -887, -887, + -885, 0, 0, 0, 0, 0, 0, -885, 0, -885, 0, 0, 0, -885, 0, 0, -885, 0, 0, 0, -885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -885, 0, -885, -885, -885, -885, 0, 0, 0, 0, 0, -885, -885, -885, -885, 0, -885, -885, -885, -885, 0, 0, 0, 1074, -885, -885, -885, -885, -885, 0, 0, -885, -885, -885, -885, 0, -885, -885, -885, -885, -885, -885, -885, -885, -885, 0, 0, 0, -885, -885, 0, -885, 0, 0, 0, -885, -885, 0, -885, -885, -885, -885, // State 1011 - -890, 0, 0, 0, 0, 0, 0, -890, 0, -890, 0, 0, 0, -890, 0, 0, -890, 0, 0, 0, -890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -890, 0, -890, -890, -890, -890, 0, 0, 0, 0, 0, -890, -890, -890, -890, 0, -890, -890, -890, -890, 0, 0, 0, 1072, -890, -890, -890, -890, -890, 0, 0, -890, -890, -890, -890, 0, -890, -890, -890, -890, -890, -890, -890, -890, -890, 0, 0, 0, -890, -890, 0, -890, 0, 0, 0, -890, -890, 0, -890, -890, -890, -890, + -886, 0, 0, 0, 0, 0, 0, -886, 0, -886, 0, 0, 0, -886, 0, 0, -886, 0, 0, 0, -886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -886, 0, -886, -886, -886, -886, 0, 0, 0, 0, 0, -886, -886, -886, -886, 0, -886, -886, -886, -886, 0, 0, 0, 0, -886, -886, -886, -886, -886, 0, 0, -886, -886, -886, -886, 0, -886, -886, -886, -886, -886, -886, -886, -886, -886, 0, 0, 0, -886, -886, 0, -886, 0, 0, 0, -886, -886, 0, -886, -886, -886, -886, // State 1012 - -891, 0, 0, 0, 0, 0, 0, -891, 0, -891, 0, 0, 0, -891, 0, 0, -891, 0, 0, 0, -891, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -891, 0, -891, -891, -891, -891, 0, 0, 0, 0, 0, -891, -891, -891, -891, 0, -891, -891, -891, -891, 0, 0, 0, 0, -891, -891, -891, -891, -891, 0, 0, -891, -891, -891, -891, 0, -891, -891, -891, -891, -891, -891, -891, -891, -891, 0, 0, 0, -891, -891, 0, -891, 0, 0, 0, -891, -891, 0, -891, -891, -891, -891, + -889, 0, 0, 0, 0, 0, 0, -889, 0, -889, 0, 0, 0, -889, 0, 0, -889, 0, 0, 0, -889, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -889, 0, -889, -889, -889, -889, 0, 0, 0, 0, 0, -889, -889, -889, -889, 0, -889, -889, -889, -889, 0, 0, 0, 1075, -889, -889, -889, -889, -889, 0, 0, -889, -889, -889, -889, 0, -889, -889, -889, -889, -889, -889, -889, -889, -889, 0, 0, 0, -889, -889, 0, -889, 0, 0, 0, -889, -889, 0, -889, -889, -889, -889, // State 1013 - -339, 0, 0, 0, 0, 0, 0, -339, 0, -339, 0, 0, 0, -339, 0, 0, -339, 0, 0, 0, -339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -339, 0, -339, -339, -339, -339, 0, 0, 0, 0, 0, -339, -339, -339, -339, 0, -339, -339, -339, -339, 0, -339, -339, -339, -339, -339, -339, -339, -339, 0, 0, -339, -339, -339, -339, 0, -339, -339, -339, -339, -339, -339, -339, -339, -339, 0, 0, 0, -339, -339, 0, -339, 0, 0, 0, -339, -339, 0, -339, -339, -339, -339, + -890, 0, 0, 0, 0, 0, 0, -890, 0, -890, 0, 0, 0, -890, 0, 0, -890, 0, 0, 0, -890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -890, 0, -890, -890, -890, -890, 0, 0, 0, 0, 0, -890, -890, -890, -890, 0, -890, -890, -890, -890, 0, 0, 0, 0, -890, -890, -890, -890, -890, 0, 0, -890, -890, -890, -890, 0, -890, -890, -890, -890, -890, -890, -890, -890, -890, 0, 0, 0, -890, -890, 0, -890, 0, 0, 0, -890, -890, 0, -890, -890, -890, -890, // State 1014 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -339, 0, 0, 0, 0, 0, 0, -339, 0, -339, 0, 0, 0, -339, 0, 0, -339, 0, 0, 0, -339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -339, 0, -339, -339, -339, -339, 0, 0, 0, 0, 0, -339, -339, -339, -339, 0, -339, -339, -339, -339, 0, -339, -339, -339, -339, -339, -339, -339, -339, 0, 0, -339, -339, -339, -339, 0, -339, -339, -339, -339, -339, -339, -339, -339, -339, 0, 0, 0, -339, -339, 0, -339, 0, 0, 0, -339, -339, 0, -339, -339, -339, -339, // State 1015 - 0, 0, 0, 0, 0, 0, 0, -828, 0, -828, 0, 0, 0, -828, 0, 0, -828, 0, 0, 0, -828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -828, 0, -828, -828, -828, -828, 0, 0, 0, 0, 0, -828, -828, -828, -828, 0, -828, -828, -828, -828, 0, 0, 0, 0, -828, -828, -828, -828, -828, 0, 0, -828, -828, -828, -828, 0, -828, -828, -828, -828, -828, -828, -828, -828, -828, 0, 0, 0, -828, -828, 0, -828, 0, 0, 0, -828, -828, 0, -828, -828, -828, -828, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1016 - 1075, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, + 0, 0, 0, 0, 0, 0, 0, -829, 0, -829, 0, 0, 0, -829, 0, 0, -829, 0, 0, 0, -829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -829, 0, -829, -829, -829, -829, 0, 0, 0, 0, 0, -829, -829, -829, -829, 0, -829, -829, -829, -829, 0, 0, 0, 0, -829, -829, -829, -829, -829, 0, 0, -829, -829, -829, -829, 0, -829, -829, -829, -829, -829, -829, -829, -829, -829, 0, 0, 0, -829, -829, 0, -829, 0, 0, 0, -829, -829, 0, -829, -829, -829, -829, // State 1017 - 0, 0, 0, 0, 0, 0, 0, -825, 0, -825, 0, 0, 0, -825, 0, 0, -825, 0, 0, 0, -825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -825, 0, -825, -825, -825, -825, 0, 0, 0, 0, 0, -825, -825, -825, -825, 0, -825, -825, -825, -825, 0, 0, 0, 0, -825, -825, -825, -825, -825, 0, 0, -825, -825, -825, -825, 0, -825, -825, -825, -825, -825, -825, -825, -825, -825, 0, 0, 0, -825, -825, 0, -825, 0, 0, 0, -825, -825, 0, -825, -825, -825, -825, + 1078, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, // State 1018 - 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1077, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -826, 0, -826, 0, 0, 0, -826, 0, 0, -826, 0, 0, 0, -826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -826, 0, -826, -826, -826, -826, 0, 0, 0, 0, 0, -826, -826, -826, -826, 0, -826, -826, -826, -826, 0, 0, 0, 0, -826, -826, -826, -826, -826, 0, 0, -826, -826, -826, -826, 0, -826, -826, -826, -826, -826, -826, -826, -826, -826, 0, 0, 0, -826, -826, 0, -826, 0, 0, 0, -826, -826, 0, -826, -826, -826, -826, // State 1019 - 0, 0, 0, 0, 0, 0, 0, -833, 0, -833, 0, 0, 0, -833, 0, 0, -833, 0, 0, 0, -833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -833, 0, -833, -833, -833, -833, 0, 0, 0, 0, 0, -833, -833, -833, -833, 0, -833, -833, -833, -833, 0, 0, 0, 0, -833, -833, -833, -833, -833, 0, 0, -833, -833, -833, -833, 0, -833, -833, -833, -833, -833, -833, -833, -833, -833, 0, 0, 0, -833, -833, 0, -833, 0, 0, 0, -833, -833, 0, -833, -833, -833, -833, + 1079, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1080, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1020 - 1078, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, + 0, 0, 0, 0, 0, 0, 0, -834, 0, -834, 0, 0, 0, -834, 0, 0, -834, 0, 0, 0, -834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -834, 0, -834, -834, -834, -834, 0, 0, 0, 0, 0, -834, -834, -834, -834, 0, -834, -834, -834, -834, 0, 0, 0, 0, -834, -834, -834, -834, -834, 0, 0, -834, -834, -834, -834, 0, -834, -834, -834, -834, -834, -834, -834, -834, -834, 0, 0, 0, -834, -834, 0, -834, 0, 0, 0, -834, -834, 0, -834, -834, -834, -834, // State 1021 - -920, 0, 0, 0, 0, 0, 0, -920, 0, -920, 0, 0, 0, -920, 0, 0, -920, 0, 0, 0, -920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -920, 0, -920, -920, -920, -920, 0, 0, 0, 0, 0, -920, -920, -920, -920, 0, -920, -920, -920, -920, 0, 0, 0, 0, -920, -920, -920, -920, -920, 0, 0, -920, -920, -920, -920, 0, -920, -920, -920, -920, -920, -920, -920, -920, -920, 0, 0, 0, -920, -920, 0, -920, 0, 0, 0, -920, -920, 0, -920, -920, -920, -920, + 1081, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, // State 1022 - 0, 0, -197, -197, 0, -197, 0, -197, 0, -197, -197, 0, 0, -197, 0, -197, -197, 0, 0, -197, 0, -197, -197, 0, 0, -224, 0, 0, -197, -197, 0, -197, 0, -197, -197, -197, -197, 0, 0, -197, 0, 0, 0, 0, -197, 0, -197, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, -197, -197, 0, 0, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -923, 0, 0, 0, 0, 0, 0, -923, 0, -923, 0, 0, 0, -923, 0, 0, -923, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -923, 0, -923, -923, -923, -923, 0, 0, 0, 0, 0, -923, -923, -923, -923, 0, -923, -923, -923, -923, 0, 0, 0, 0, -923, -923, -923, -923, -923, 0, 0, -923, -923, -923, -923, 0, -923, -923, -923, -923, -923, -923, -923, -923, -923, 0, 0, 0, -923, -923, 0, -923, 0, 0, 0, -923, -923, 0, -923, -923, -923, -923, // State 1023 - 0, 0, -191, -191, 0, -191, 0, -191, 0, -191, -191, 0, 0, -191, 0, -191, -191, 0, 0, -191, 0, -191, -191, 0, 0, -218, 0, 0, -191, -191, 0, -191, 0, -191, -191, -191, -191, 0, 0, -191, 0, 0, 0, 0, -191, 0, -191, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, -191, -191, 0, 0, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -197, -197, 0, -197, 0, -197, 0, -197, -197, 0, 0, -197, 0, -197, -197, 0, 0, -197, 0, -197, -197, 0, 0, -224, 0, 0, -197, -197, 0, -197, 0, -197, -197, -197, -197, 0, 0, -197, 0, 0, 0, 0, -197, 0, -197, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, -197, -197, 0, 0, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1024 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -191, -191, 0, -191, 0, -191, 0, -191, -191, 0, 0, -191, 0, -191, -191, 0, 0, -191, 0, -191, -191, 0, 0, -218, 0, 0, -191, -191, 0, -191, 0, -191, -191, -191, -191, 0, 0, -191, 0, 0, 0, 0, -191, 0, -191, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, -191, -191, 0, 0, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1025 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -929, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1026 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1027 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, -697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -657, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1028 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1083, 0, 0, 0, 0, 0, 0, 0, 0, 0, -682, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, -698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1029 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1084, 0, 0, 0, 0, 0, 0, 0, 0, 0, -687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1086, 0, 0, 0, 0, 0, 0, 0, 0, 0, -683, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1030 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1086, 0, 0, 0, 0, 0, 0, 0, 0, 0, -678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1087, 0, 0, 0, 0, 0, 0, 0, 0, 0, -688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1031 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1089, 0, 0, 0, 0, 0, 0, 0, 0, 0, -679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1032 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1033 - -407, 0, 0, 0, 0, 0, 0, -407, 0, -407, 0, 0, 0, -407, 0, 0, -407, 0, 0, 0, -407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -407, 0, -407, -407, -407, -407, 0, 0, 0, 0, 0, -407, -407, -407, -407, 0, -407, -407, -407, -407, 0, 0, 0, 0, -407, -407, -407, -407, -407, 0, 0, -407, -407, -407, -407, 0, -407, -407, -407, -407, -407, -407, -407, -407, -407, 0, 0, 0, -407, -407, 0, -407, 0, 0, 0, -407, -407, 0, -407, -407, -407, -407, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1034 - -412, 0, 0, 0, 0, 0, 0, -412, 0, -412, 0, 0, 0, -412, 0, 0, -412, 0, 0, 0, -412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -412, 0, -412, -412, -412, -412, 0, 0, 0, 0, 0, -412, -412, -412, -412, 0, -412, -412, -412, -412, 0, 0, 0, 0, -412, -412, -412, -412, -412, 0, 0, -412, -412, -412, -412, 0, -412, -412, -412, -412, -412, -412, -412, -412, -412, 0, 0, 0, -412, -412, 0, -412, 0, 0, 0, -412, -412, 0, -412, -412, -412, -412, + -407, 0, 0, 0, 0, 0, 0, -407, 0, -407, 0, 0, 0, -407, 0, 0, -407, 0, 0, 0, -407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -407, 0, -407, -407, -407, -407, 0, 0, 0, 0, 0, -407, -407, -407, -407, 0, -407, -407, -407, -407, 0, 0, 0, 0, -407, -407, -407, -407, -407, 0, 0, -407, -407, -407, -407, 0, -407, -407, -407, -407, -407, -407, -407, -407, -407, 0, 0, 0, -407, -407, 0, -407, 0, 0, 0, -407, -407, 0, -407, -407, -407, -407, // State 1035 - -402, 0, 0, 0, 0, 0, 0, -402, 0, -402, 0, 0, 0, -402, 0, 0, -402, 0, 0, 0, -402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -402, 0, -402, -402, -402, -402, 0, 0, 0, 0, 0, -402, -402, -402, -402, 0, -402, -402, -402, -402, 0, 0, 0, 0, -402, -402, -402, -402, -402, 0, 0, -402, -402, -402, -402, 0, -402, -402, -402, -402, -402, -402, -402, -402, -402, 0, 0, 0, -402, -402, 0, -402, 0, 0, 0, -402, -402, 0, -402, -402, -402, -402, + -412, 0, 0, 0, 0, 0, 0, -412, 0, -412, 0, 0, 0, -412, 0, 0, -412, 0, 0, 0, -412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -412, 0, -412, -412, -412, -412, 0, 0, 0, 0, 0, -412, -412, -412, -412, 0, -412, -412, -412, -412, 0, 0, 0, 0, -412, -412, -412, -412, -412, 0, 0, -412, -412, -412, -412, 0, -412, -412, -412, -412, -412, -412, -412, -412, -412, 0, 0, 0, -412, -412, 0, -412, 0, 0, 0, -412, -412, 0, -412, -412, -412, -412, // State 1036 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -402, 0, 0, 0, 0, 0, 0, -402, 0, -402, 0, 0, 0, -402, 0, 0, -402, 0, 0, 0, -402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -402, 0, -402, -402, -402, -402, 0, 0, 0, 0, 0, -402, -402, -402, -402, 0, -402, -402, -402, -402, 0, 0, 0, 0, -402, -402, -402, -402, -402, 0, 0, -402, -402, -402, -402, 0, -402, -402, -402, -402, -402, -402, -402, -402, -402, 0, 0, 0, -402, -402, 0, -402, 0, 0, 0, -402, -402, 0, -402, -402, -402, -402, // State 1037 - -409, 0, 0, 0, 0, 0, 0, -409, 0, -409, 0, 0, 0, -409, 0, 0, -409, 0, 0, 0, -409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -409, 0, -409, -409, -409, -409, 0, 0, 0, 0, 0, -409, -409, -409, -409, 0, -409, -409, -409, -409, 0, 0, 0, 0, -409, -409, -409, -409, -409, 0, 0, -409, -409, -409, -409, 0, -409, -409, -409, -409, -409, -409, -409, -409, -409, 0, 0, 0, -409, -409, 0, -409, 0, 0, 0, -409, -409, 0, -409, -409, -409, -409, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1038 - 0, 0, 0, 0, 0, 0, 0, 0, -617, 0, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -409, 0, 0, 0, 0, 0, 0, -409, 0, -409, 0, 0, 0, -409, 0, 0, -409, 0, 0, 0, -409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -409, 0, -409, -409, -409, -409, 0, 0, 0, 0, 0, -409, -409, -409, -409, 0, -409, -409, -409, -409, 0, 0, 0, 0, -409, -409, -409, -409, -409, 0, 0, -409, -409, -409, -409, 0, -409, -409, -409, -409, -409, -409, -409, -409, -409, 0, 0, 0, -409, -409, 0, -409, 0, 0, 0, -409, -409, 0, -409, -409, -409, -409, // State 1039 - 0, 0, 0, 0, 0, 0, 0, 0, -602, 0, 0, 0, 0, 0, 0, 1092, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -618, 0, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1040 - 0, 0, 0, 0, 0, 0, 0, 0, -630, 0, 0, 0, 0, 0, 0, 1094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -603, 0, 0, 0, 0, 0, 0, 1095, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1041 - 0, 0, 0, 0, 0, 0, 0, 0, -635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -631, 0, 0, 0, 0, 0, 0, 1097, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1042 - 0, 0, 0, 0, 0, 0, 0, 0, -642, 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1043 - 0, 0, 0, 0, 0, 0, 0, 0, -632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -643, 0, 0, 0, 0, 0, 0, 1099, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1044 - -536, 0, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1045 - -433, 0, 0, 0, 0, 0, 0, -433, 0, -433, 0, 0, 0, -433, 0, 0, -433, 0, 0, 0, -433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -433, 0, -433, -433, -433, -433, 0, 0, 0, 0, 0, -433, -433, -433, -433, 0, -433, -433, -433, -433, 0, 0, 0, 0, -433, -433, -433, -433, -433, 0, 0, -433, -433, -433, -433, 0, -433, -433, -433, -433, -433, -433, -433, -433, -433, 0, 0, 0, -433, -433, 0, -433, 0, 0, 0, -433, -433, 0, -433, -433, -433, -433, + -537, 0, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1046 - -107, 0, 0, 0, 0, 0, 0, -107, 0, -107, 0, 0, 0, -107, 0, 0, -107, 0, 0, 0, -107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -107, 0, -107, -107, -107, -107, 0, 0, 0, 0, 0, -107, -107, -107, -107, 0, -107, -107, -107, -107, -107, -107, 0, 0, -107, -107, -107, -107, -107, 0, 0, -107, -107, -107, -107, 0, -107, -107, -107, -107, -107, -107, -107, -107, -107, 0, 0, 0, -107, -107, 0, -107, 0, 0, 0, -107, -107, 0, -107, -107, -107, -107, + -433, 0, 0, 0, 0, 0, 0, -433, 0, -433, 0, 0, 0, -433, 0, 0, -433, 0, 0, 0, -433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -433, 0, -433, -433, -433, -433, 0, 0, 0, 0, 0, -433, -433, -433, -433, 0, -433, -433, -433, -433, 0, 0, 0, 0, -433, -433, -433, -433, -433, 0, 0, -433, -433, -433, -433, 0, -433, -433, -433, -433, -433, -433, -433, -433, -433, 0, 0, 0, -433, -433, 0, -433, 0, 0, 0, -433, -433, 0, -433, -433, -433, -433, // State 1047 - -499, 0, 0, 0, 0, 0, 0, -499, 0, -499, 0, 0, 0, -499, 0, 0, -499, 0, 0, 0, -499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -499, 0, -499, -499, -499, -499, 0, 0, 0, 0, 0, -499, -499, -499, -499, 0, -499, -499, -499, -499, 0, 0, 0, 0, -499, -499, -499, -499, -499, 0, 0, -499, -499, -499, -499, 0, -499, -499, -499, -499, -499, -499, -499, -499, -499, 0, 0, 0, -499, -499, 0, -499, 0, 0, 0, -499, -499, 0, -499, -499, -499, -499, + -107, 0, 0, 0, 0, 0, 0, -107, 0, -107, 0, 0, 0, -107, 0, 0, -107, 0, 0, 0, -107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -107, 0, -107, -107, -107, -107, 0, 0, 0, 0, 0, -107, -107, -107, -107, 0, -107, -107, -107, -107, -107, -107, 0, 0, -107, -107, -107, -107, -107, 0, 0, -107, -107, -107, -107, 0, -107, -107, -107, -107, -107, -107, -107, -107, -107, 0, 0, 0, -107, -107, 0, -107, 0, 0, 0, -107, -107, 0, -107, -107, -107, -107, // State 1048 - 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -500, 0, 0, 0, 0, 0, 0, -500, 0, -500, 0, 0, 0, -500, 0, 0, -500, 0, 0, 0, -500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -500, 0, -500, -500, -500, -500, 0, 0, 0, 0, 0, -500, -500, -500, -500, 0, -500, -500, -500, -500, 0, 0, 0, 0, -500, -500, -500, -500, -500, 0, 0, -500, -500, -500, -500, 0, -500, -500, -500, -500, -500, -500, -500, -500, -500, 0, 0, 0, -500, -500, 0, -500, 0, 0, 0, -500, -500, 0, -500, -500, -500, -500, // State 1049 - 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1050 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1051 - 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1052 - 0, 0, 0, 0, 0, 0, 0, 0, 1116, 0, 0, 0, 0, 0, 0, 1117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -893, 0, 0, 0, 0, 0, 0, -893, 0, 0, 0, 0, 0, 0, 0, 0, 0, -893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -893, 0, 0, 0, -893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -893, 0, -893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -893, // State 1053 - 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, // State 1054 - 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1119, 0, 0, 0, 0, 0, 0, 1120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1055 - 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, -523, 0, -523, -523, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1056 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -818, 0, -818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1057 - 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, -524, 0, -524, -524, 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1058 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1059 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1060 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1061 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1062 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1063 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 364, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1064 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1065 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 365, 0, 0, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1066 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1067 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1068 - 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, 0, 0, 0, 0, 0, -482, 0, 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, 0, 0, -482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, -482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1069 - -500, 0, 0, 0, 0, 0, 0, -500, 0, -500, 0, 0, 0, -500, 0, 0, -500, 0, 0, 0, -500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -500, 0, -500, -500, -500, -500, 0, 0, 0, 0, 0, -500, -500, -500, -500, 0, -500, -500, -500, -500, 0, 0, 0, 0, -500, -500, -500, -500, -500, 0, 0, -500, -500, -500, -500, 0, -500, -500, -500, -500, -500, -500, -500, -500, -500, 0, 0, 0, -500, -500, 0, -500, 0, 0, 0, -500, -500, 0, -500, -500, -500, -500, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1070 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1071 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1072 - -344, 0, 0, 0, 0, 0, 0, -344, 0, -344, 0, 0, 0, -344, 0, 0, -344, 0, 0, 0, -344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -344, 0, -344, -344, -344, -344, 0, 0, 0, 0, 0, -344, -344, -344, -344, 0, -344, -344, -344, -344, 0, -344, -344, -344, -344, -344, -344, -344, -344, 0, 0, -344, -344, -344, -344, 0, -344, -344, -344, -344, -344, -344, -344, -344, -344, 0, 0, 0, -344, -344, 0, -344, 0, 0, 0, -344, -344, 0, -344, -344, -344, -344, + -501, 0, 0, 0, 0, 0, 0, -501, 0, -501, 0, 0, 0, -501, 0, 0, -501, 0, 0, 0, -501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -501, 0, -501, -501, -501, -501, 0, 0, 0, 0, 0, -501, -501, -501, -501, 0, -501, -501, -501, -501, 0, 0, 0, 0, -501, -501, -501, -501, -501, 0, 0, -501, -501, -501, -501, 0, -501, -501, -501, -501, -501, -501, -501, -501, -501, 0, 0, 0, -501, -501, 0, -501, 0, 0, 0, -501, -501, 0, -501, -501, -501, -501, // State 1073 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1074 - 0, 0, 0, 0, 0, 0, 0, -826, 0, -826, 0, 0, 0, -826, 0, 0, -826, 0, 0, 0, -826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -826, 0, -826, -826, -826, -826, 0, 0, 0, 0, 0, -826, -826, -826, -826, 0, -826, -826, -826, -826, 0, 0, 0, 0, -826, -826, -826, -826, -826, 0, 0, -826, -826, -826, -826, 0, -826, -826, -826, -826, -826, -826, -826, -826, -826, 0, 0, 0, -826, -826, 0, -826, 0, 0, 0, -826, -826, 0, -826, -826, -826, -826, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1075 - 0, 0, 0, 0, 0, 0, 0, -834, 0, -834, 0, 0, 0, -834, 0, 0, -834, 0, 0, 0, -834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -834, 0, -834, -834, -834, -834, 0, 0, 0, 0, 0, -834, -834, -834, -834, 0, -834, -834, -834, -834, 0, 0, 0, 0, -834, -834, -834, -834, -834, 0, 0, -834, -834, -834, -834, 0, -834, -834, -834, -834, -834, -834, -834, -834, -834, 0, 0, 0, -834, -834, 0, -834, 0, 0, 0, -834, -834, 0, -834, -834, -834, -834, + -344, 0, 0, 0, 0, 0, 0, -344, 0, -344, 0, 0, 0, -344, 0, 0, -344, 0, 0, 0, -344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -344, 0, -344, -344, -344, -344, 0, 0, 0, 0, 0, -344, -344, -344, -344, 0, -344, -344, -344, -344, 0, -344, -344, -344, -344, -344, -344, -344, -344, 0, 0, -344, -344, -344, -344, 0, -344, -344, -344, -344, -344, -344, -344, -344, -344, 0, 0, 0, -344, -344, 0, -344, 0, 0, 0, -344, -344, 0, -344, -344, -344, -344, // State 1076 - 1125, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1077 - 0, 0, 0, 0, 0, 0, 0, -831, 0, -831, 0, 0, 0, -831, 0, 0, -831, 0, 0, 0, -831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -831, 0, -831, -831, -831, -831, 0, 0, 0, 0, 0, -831, -831, -831, -831, 0, -831, -831, -831, -831, 0, 0, 0, 0, -831, -831, -831, -831, -831, 0, 0, -831, -831, -831, -831, 0, -831, -831, -831, -831, -831, -831, -831, -831, -831, 0, 0, 0, -831, -831, 0, -831, 0, 0, 0, -831, -831, 0, -831, -831, -831, -831, + 0, 0, 0, 0, 0, 0, 0, -827, 0, -827, 0, 0, 0, -827, 0, 0, -827, 0, 0, 0, -827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -827, 0, -827, -827, -827, -827, 0, 0, 0, 0, 0, -827, -827, -827, -827, 0, -827, -827, -827, -827, 0, 0, 0, 0, -827, -827, -827, -827, -827, 0, 0, -827, -827, -827, -827, 0, -827, -827, -827, -827, -827, -827, -827, -827, -827, 0, 0, 0, -827, -827, 0, -827, 0, 0, 0, -827, -827, 0, -827, -827, -827, -827, // State 1078 - 0, 0, -193, -193, 0, -193, 0, -193, 0, -193, -193, 0, 0, -193, 0, -193, -193, 0, 0, -193, 0, -193, -193, 0, 0, -220, 0, 0, -193, -193, 0, -193, 0, -193, -193, -193, -193, 0, 0, -193, 0, 0, 0, 0, -193, 0, -193, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, -193, -193, 0, 0, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -835, 0, -835, 0, 0, 0, -835, 0, 0, -835, 0, 0, 0, -835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -835, 0, -835, -835, -835, -835, 0, 0, 0, 0, 0, -835, -835, -835, -835, 0, -835, -835, -835, -835, 0, 0, 0, 0, -835, -835, -835, -835, -835, 0, 0, -835, -835, -835, -835, 0, -835, -835, -835, -835, -835, -835, -835, -835, -835, 0, 0, 0, -835, -835, 0, -835, 0, 0, 0, -835, -835, 0, -835, -835, -835, -835, // State 1079 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -931, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1128, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, // State 1080 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1126, 0, 0, 0, 0, 0, 0, 0, 0, 0, -688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -832, 0, -832, 0, 0, 0, -832, 0, 0, -832, 0, 0, 0, -832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -832, 0, -832, -832, -832, -832, 0, 0, 0, 0, 0, -832, -832, -832, -832, 0, -832, -832, -832, -832, 0, 0, 0, 0, -832, -832, -832, -832, -832, 0, 0, -832, -832, -832, -832, 0, -832, -832, -832, -832, -832, -832, -832, -832, -832, 0, 0, 0, -832, -832, 0, -832, 0, 0, 0, -832, -832, 0, -832, -832, -832, -832, // State 1081 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1128, 0, 0, 0, 0, 0, 0, 0, 0, 0, -679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -193, -193, 0, -193, 0, -193, 0, -193, -193, 0, 0, -193, 0, -193, -193, 0, 0, -193, 0, -193, -193, 0, 0, -220, 0, 0, -193, -193, 0, -193, 0, -193, -193, -193, -193, 0, 0, -193, 0, 0, 0, 0, -193, 0, -193, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, -193, -193, 0, 0, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1082 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1083 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1129, 0, 0, 0, 0, 0, 0, 0, 0, 0, -689, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1084 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1129, 0, 0, 0, 0, 0, 0, 0, 0, 0, -684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1131, 0, 0, 0, 0, 0, 0, 0, 0, 0, -680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1085 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1086 - -404, 0, 0, 0, 0, 0, 0, -404, 0, -404, 0, 0, 0, -404, 0, 0, -404, 0, 0, 0, -404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -404, 0, -404, -404, -404, -404, 0, 0, 0, 0, 0, -404, -404, -404, -404, 0, -404, -404, -404, -404, 0, 0, 0, 0, -404, -404, -404, -404, -404, 0, 0, -404, -404, -404, -404, 0, -404, -404, -404, -404, -404, -404, -404, -404, -404, 0, 0, 0, -404, -404, 0, -404, 0, 0, 0, -404, -404, 0, -404, -404, -404, -404, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1087 - -411, 0, 0, 0, 0, 0, 0, -411, 0, -411, 0, 0, 0, -411, 0, 0, -411, 0, 0, 0, -411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -411, 0, -411, -411, -411, -411, 0, 0, 0, 0, 0, -411, -411, -411, -411, 0, -411, -411, -411, -411, 0, 0, 0, 0, -411, -411, -411, -411, -411, 0, 0, -411, -411, -411, -411, 0, -411, -411, -411, -411, -411, -411, -411, -411, -411, 0, 0, 0, -411, -411, 0, -411, 0, 0, 0, -411, -411, 0, -411, -411, -411, -411, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1132, 0, 0, 0, 0, 0, 0, 0, 0, 0, -685, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1088 - -401, 0, 0, 0, 0, 0, 0, -401, 0, -401, 0, 0, 0, -401, 0, 0, -401, 0, 0, 0, -401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -401, 0, -401, -401, -401, -401, 0, 0, 0, 0, 0, -401, -401, -401, -401, 0, -401, -401, -401, -401, 0, 0, 0, 0, -401, -401, -401, -401, -401, 0, 0, -401, -401, -401, -401, 0, -401, -401, -401, -401, -401, -401, -401, -401, -401, 0, 0, 0, -401, -401, 0, -401, 0, 0, 0, -401, -401, 0, -401, -401, -401, -401, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1089 - 0, 0, 0, 0, 0, 0, 0, 0, -608, 0, 0, 0, 0, 0, 0, 1132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -404, 0, 0, 0, 0, 0, 0, -404, 0, -404, 0, 0, 0, -404, 0, 0, -404, 0, 0, 0, -404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -404, 0, -404, -404, -404, -404, 0, 0, 0, 0, 0, -404, -404, -404, -404, 0, -404, -404, -404, -404, 0, 0, 0, 0, -404, -404, -404, -404, -404, 0, 0, -404, -404, -404, -404, 0, -404, -404, -404, -404, -404, -404, -404, -404, -404, 0, 0, 0, -404, -404, 0, -404, 0, 0, 0, -404, -404, 0, -404, -404, -404, -404, // State 1090 - 0, 0, 0, 0, 0, 0, 0, 0, -599, 0, 0, 0, 0, 0, 0, 1134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -411, 0, 0, 0, 0, 0, 0, -411, 0, -411, 0, 0, 0, -411, 0, 0, -411, 0, 0, 0, -411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -411, 0, -411, -411, -411, -411, 0, 0, 0, 0, 0, -411, -411, -411, -411, 0, -411, -411, -411, -411, 0, 0, 0, 0, -411, -411, -411, -411, -411, 0, 0, -411, -411, -411, -411, 0, -411, -411, -411, -411, -411, -411, -411, -411, -411, 0, 0, 0, -411, -411, 0, -411, 0, 0, 0, -411, -411, 0, -411, -411, -411, -411, // State 1091 - 0, 0, 0, 0, 0, 0, 0, 0, -575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -401, 0, 0, 0, 0, 0, 0, -401, 0, -401, 0, 0, 0, -401, 0, 0, -401, 0, 0, 0, -401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -401, 0, -401, -401, -401, -401, 0, 0, 0, 0, 0, -401, -401, -401, -401, 0, -401, -401, -401, -401, 0, 0, 0, 0, -401, -401, -401, -401, -401, 0, 0, -401, -401, -401, -401, 0, -401, -401, -401, -401, -401, -401, -401, -401, -401, 0, 0, 0, -401, -401, 0, -401, 0, 0, 0, -401, -401, 0, -401, -401, -401, -401, // State 1092 - 0, 0, 0, 0, 0, 0, 0, 0, -631, 0, 0, 0, 0, 0, 0, 1135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -609, 0, 0, 0, 0, 0, 0, 1135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1093 - 0, 0, 0, 0, 0, 0, 0, 0, -627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -600, 0, 0, 0, 0, 0, 0, 1137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1094 - 0, 0, 0, 0, 0, 0, 0, 0, -621, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1095 - 0, 0, 0, 0, 0, 0, 0, 0, -634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -632, 0, 0, 0, 0, 0, 0, 1138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1096 - -399, 0, 0, 0, 0, 0, 0, -399, 0, -399, 0, 0, 0, -399, 0, 0, -399, 0, 0, 0, -399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -399, 0, -399, -399, -399, -399, 0, 0, 0, 0, 0, -399, -399, -399, -399, 0, -399, -399, -399, -399, 0, 0, 0, 0, -399, -399, -399, -399, -399, 0, 0, -399, -399, -399, -399, 0, -399, -399, -399, -399, -399, -399, -399, -399, -399, 0, 0, 0, -399, -399, 0, -399, 0, 0, 0, -399, -399, 0, -399, -399, -399, -399, + 0, 0, 0, 0, 0, 0, 0, 0, -628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1097 - -108, 0, 0, 0, 0, 0, 0, -108, 0, -108, 0, 0, 0, -108, 0, 0, -108, 0, 0, 0, -108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -108, 0, -108, -108, -108, -108, 0, 0, 0, 0, 0, -108, -108, -108, -108, 0, -108, -108, -108, -108, -108, -108, 0, 0, -108, -108, -108, -108, -108, 0, 0, -108, -108, -108, -108, 0, -108, -108, -108, -108, -108, -108, -108, -108, -108, 0, 0, 0, -108, -108, 0, -108, 0, 0, 0, -108, -108, 0, -108, -108, -108, -108, + 0, 0, 0, 0, 0, 0, 0, 0, -622, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1098 - 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1099 - 0, 0, 0, 0, 0, 0, 0, -495, -264, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -399, 0, 0, 0, 0, 0, 0, -399, 0, -399, 0, 0, 0, -399, 0, 0, -399, 0, 0, 0, -399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -399, 0, -399, -399, -399, -399, 0, 0, 0, 0, 0, -399, -399, -399, -399, 0, -399, -399, -399, -399, 0, 0, 0, 0, -399, -399, -399, -399, -399, 0, 0, -399, -399, -399, -399, 0, -399, -399, -399, -399, -399, -399, -399, -399, -399, 0, 0, 0, -399, -399, 0, -399, 0, 0, 0, -399, -399, 0, -399, -399, -399, -399, // State 1100 - 0, 0, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -108, 0, 0, 0, 0, 0, 0, -108, 0, -108, 0, 0, 0, -108, 0, 0, -108, 0, 0, 0, -108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -108, 0, -108, -108, -108, -108, 0, 0, 0, 0, 0, -108, -108, -108, -108, 0, -108, -108, -108, -108, -108, -108, 0, 0, -108, -108, -108, -108, -108, 0, 0, -108, -108, -108, -108, 0, -108, -108, -108, -108, -108, -108, -108, -108, -108, 0, 0, 0, -108, -108, 0, -108, 0, 0, 0, -108, -108, 0, -108, -108, -108, -108, // State 1101 - 0, 0, 0, 0, 0, 0, 0, 0, 1139, 0, 0, 0, 0, 0, 0, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1102 - 0, 0, 0, 0, 0, 0, 0, 0, 1140, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -496, -264, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1103 - 0, 0, 0, 0, 0, 0, 0, 0, -546, 0, 0, 0, 0, 0, 0, -546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -539, 0, 0, 0, 0, 0, 0, -539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1104 - 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1142, 0, 0, 0, 0, 0, 0, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1105 - 0, 0, 0, 0, 0, 0, 0, -496, -496, 0, 0, 0, 0, 0, 0, -496, 0, 0, 0, -496, 0, 0, 0, 0, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -496, 0, 0, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -496, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1143, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1106 - 0, 0, 0, 0, 0, 0, 0, -497, -497, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, -497, 0, 0, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -547, 0, 0, 0, 0, 0, 0, -547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1107 - 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1108 - 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -497, -497, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, -497, 0, 0, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1109 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -896, 0, 0, 0, 0, 0, 0, 0, 0, 0, -896, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -896, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -498, -498, 0, 0, 0, 0, 0, 0, -498, 0, 0, 0, -498, 0, 0, 0, 0, 0, -498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -498, 0, 0, 0, -498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -498, 0, -498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1110 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1111 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1112 - 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -899, 0, 0, 0, 0, 0, 0, 0, 0, 0, -899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1113 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1114 - 0, 0, 0, 0, 0, 0, 0, 0, 1142, 0, 0, 0, 0, 0, 0, 1143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1115 - 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1116 - 0, 0, 0, 0, 0, 0, 0, -129, 1144, -129, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, -129, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, 0, -129, 0, -129, -129, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -900, 0, 0, 0, 0, 0, 0, 0, 0, 0, -900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1117 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1145, 0, 0, 0, 0, 0, 0, 1146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1118 - 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1119 - 0, 0, 0, 0, 0, 0, 0, -129, 0, -129, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, -129, -129, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, 0, -129, 0, -129, -129, + 0, 0, 0, 0, 0, 0, 0, -129, 1147, -129, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, -129, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, 0, -129, 0, -129, -129, // State 1120 - 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1121 - 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -787, 0, 0, 0, 0, 0, 0, -787, 0, 0, 0, 0, 0, 0, 0, 0, 0, -787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -787, 0, 0, 0, -787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -787, 0, -787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1122 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -129, 0, -129, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, -129, -129, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, 0, -129, 0, -129, -129, // State 1123 - -341, 0, 0, 0, 0, 0, 0, -341, 0, -341, 0, 0, 0, -341, 0, 0, -341, 0, 0, 0, -341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -341, 0, -341, -341, -341, -341, 0, 0, 0, 0, 0, -341, -341, -341, -341, 0, -341, -341, -341, -341, 0, -341, -341, -341, -341, -341, -341, -341, -341, 0, 0, -341, -341, -341, -341, 0, -341, -341, -341, -341, -341, -341, -341, -341, -341, 0, 0, 0, -341, -341, 0, -341, 0, 0, 0, -341, -341, 0, -341, -341, -341, -341, + 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1124 - 0, 0, 0, 0, 0, 0, 0, -832, 0, -832, 0, 0, 0, -832, 0, 0, -832, 0, 0, 0, -832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -832, 0, -832, -832, -832, -832, 0, 0, 0, 0, 0, -832, -832, -832, -832, 0, -832, -832, -832, -832, 0, 0, 0, 0, -832, -832, -832, -832, -832, 0, 0, -832, -832, -832, -832, 0, -832, -832, -832, -832, -832, -832, -832, -832, -832, 0, 0, 0, -832, -832, 0, -832, 0, 0, 0, -832, -832, 0, -832, -832, -832, -832, + 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1125 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1126 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -685, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -341, 0, 0, 0, 0, 0, 0, -341, 0, -341, 0, 0, 0, -341, 0, 0, -341, 0, 0, 0, -341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -341, 0, -341, -341, -341, -341, 0, 0, 0, 0, 0, -341, -341, -341, -341, 0, -341, -341, -341, -341, 0, -341, -341, -341, -341, -341, -341, -341, -341, 0, 0, -341, -341, -341, -341, 0, -341, -341, -341, -341, -341, -341, -341, -341, -341, 0, 0, 0, -341, -341, 0, -341, 0, 0, 0, -341, -341, 0, -341, -341, -341, -341, // State 1127 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -833, 0, -833, 0, 0, 0, -833, 0, 0, -833, 0, 0, 0, -833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -833, 0, -833, -833, -833, -833, 0, 0, 0, 0, 0, -833, -833, -833, -833, 0, -833, -833, -833, -833, 0, 0, 0, 0, -833, -833, -833, -833, -833, 0, 0, -833, -833, -833, -833, 0, -833, -833, -833, -833, -833, -833, -833, -833, -833, 0, 0, 0, -833, -833, 0, -833, 0, 0, 0, -833, -833, 0, -833, -833, -833, -833, // State 1128 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -657, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -662, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1129 - -403, 0, 0, 0, 0, 0, 0, -403, 0, -403, 0, 0, 0, -403, 0, 0, -403, 0, 0, 0, -403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -403, 0, -403, -403, -403, -403, 0, 0, 0, 0, 0, -403, -403, -403, -403, 0, -403, -403, -403, -403, 0, 0, 0, 0, -403, -403, -403, -403, -403, 0, 0, -403, -403, -403, -403, 0, -403, -403, -403, -403, -403, -403, -403, -403, -403, 0, 0, 0, -403, -403, 0, -403, 0, 0, 0, -403, -403, 0, -403, -403, -403, -403, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1158, 0, 0, 0, 0, 0, 0, 0, 0, 0, -686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1130 - -397, 0, 0, 0, 0, 0, 0, -397, 0, -397, 0, 0, 0, -397, 0, 0, -397, 0, 0, 0, -397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -397, 0, -397, -397, -397, -397, 0, 0, 0, 0, 0, -397, -397, -397, -397, 0, -397, -397, -397, -397, 0, 0, 0, 0, -397, -397, -397, -397, -397, 0, 0, -397, -397, -397, -397, 0, -397, -397, -397, -397, -397, -397, -397, -397, -397, 0, 0, 0, -397, -397, 0, -397, 0, 0, 0, -397, -397, 0, -397, -397, -397, -397, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1131 - 0, 0, 0, 0, 0, 0, 0, 0, -581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1132 - 0, 0, 0, 0, 0, 0, 0, 0, -605, 0, 0, 0, 0, 0, 0, 1156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -403, 0, 0, 0, 0, 0, 0, -403, 0, -403, 0, 0, 0, -403, 0, 0, -403, 0, 0, 0, -403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -403, 0, -403, -403, -403, -403, 0, 0, 0, 0, 0, -403, -403, -403, -403, 0, -403, -403, -403, -403, 0, 0, 0, 0, -403, -403, -403, -403, -403, 0, 0, -403, -403, -403, -403, 0, -403, -403, -403, -403, -403, -403, -403, -403, -403, 0, 0, 0, -403, -403, 0, -403, 0, 0, 0, -403, -403, 0, -403, -403, -403, -403, // State 1133 - 0, 0, 0, 0, 0, 0, 0, 0, -572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -397, 0, 0, 0, 0, 0, 0, -397, 0, -397, 0, 0, 0, -397, 0, 0, -397, 0, 0, 0, -397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -397, 0, -397, -397, -397, -397, 0, 0, 0, 0, 0, -397, -397, -397, -397, 0, -397, -397, -397, -397, 0, 0, 0, 0, -397, -397, -397, -397, -397, 0, 0, -397, -397, -397, -397, 0, -397, -397, -397, -397, -397, -397, -397, -397, -397, 0, 0, 0, -397, -397, 0, -397, 0, 0, 0, -397, -397, 0, -397, -397, -397, -397, // State 1134 - 0, 0, 0, 0, 0, 0, 0, 0, -628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1135 - 0, 0, 0, 0, 0, 0, 0, 0, -622, 0, 0, 0, 0, 0, 0, 399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -606, 0, 0, 0, 0, 0, 0, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1136 - 0, 0, 0, 0, 0, 0, 0, 0, -618, 0, 0, 0, 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -573, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1137 - 0, 0, 0, 0, 0, 0, 0, 0, -603, 0, 0, 0, 0, 0, 0, 1161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1138 - 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -623, 0, 0, 0, 0, 0, 0, 399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1139 - 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -619, 0, 0, 0, 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1140 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -604, 0, 0, 0, 0, 0, 0, 1164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1141 - 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1142 - 0, 0, 0, 0, 0, 0, 0, -130, 1169, -130, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, -130, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, 0, -130, 0, -130, -130, + 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1143 - 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1144 - 0, 0, 0, 0, 0, 0, 0, -130, 0, -130, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, -130, -130, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, 0, -130, 0, -130, -130, + 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1145 - 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -130, 1172, -130, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, -130, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, 0, -130, 0, -130, -130, // State 1146 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1147 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -130, 0, -130, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, -130, -130, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, 0, -130, 0, -130, -130, // State 1148 - 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1149 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1150 - 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1151 - -885, 0, 0, 0, 0, 0, 0, -885, 0, -885, 0, 0, 0, -885, 0, 0, -885, 0, 0, 0, -885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -885, 0, -885, -885, -885, -885, 0, 0, 0, 0, 0, -885, -885, -885, -885, 0, -885, -885, -885, -885, 0, 0, 0, 0, -885, -885, -885, -885, -885, 0, 0, -885, -885, -885, -885, 0, -885, -885, -885, -885, -885, -885, -885, -885, -885, 0, 0, 0, -885, -885, 0, -885, 0, 0, 0, -885, -885, 0, -885, -885, -885, -885, + 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1152 - -889, 0, 0, 0, 0, 0, 0, -889, 0, -889, 0, 0, 0, -889, 0, 0, -889, 0, 0, 0, -889, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -889, 0, -889, -889, -889, -889, 0, 0, 0, 0, 0, -889, -889, -889, -889, 0, -889, -889, -889, -889, 0, 0, 0, 0, -889, -889, -889, -889, -889, 0, 0, -889, -889, -889, -889, 0, -889, -889, -889, -889, -889, -889, -889, -889, -889, 0, 0, 0, -889, -889, 0, -889, 0, 0, 0, -889, -889, 0, -889, -889, -889, -889, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1153 - -345, 0, 0, 0, 0, 0, 0, -345, 0, -345, 0, 0, 0, -345, 0, 0, -345, 0, 0, 0, -345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -345, 0, -345, -345, -345, -345, 0, 0, 0, 0, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, -345, -345, -345, -345, 0, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, -345, -345, -345, -345, -345, 0, 0, 0, -345, -345, 0, -345, 0, 0, 0, -345, -345, 0, -345, -345, -345, -345, + 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1154 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -884, 0, 0, 0, 0, 0, 0, -884, 0, -884, 0, 0, 0, -884, 0, 0, -884, 0, 0, 0, -884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -884, 0, -884, -884, -884, -884, 0, 0, 0, 0, 0, -884, -884, -884, -884, 0, -884, -884, -884, -884, 0, 0, 0, 0, -884, -884, -884, -884, -884, 0, 0, -884, -884, -884, -884, 0, -884, -884, -884, -884, -884, -884, -884, -884, -884, 0, 0, 0, -884, -884, 0, -884, 0, 0, 0, -884, -884, 0, -884, -884, -884, -884, // State 1155 - 0, 0, 0, 0, 0, 0, 0, 0, -578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -888, 0, 0, 0, 0, 0, 0, -888, 0, -888, 0, 0, 0, -888, 0, 0, -888, 0, 0, 0, -888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -888, 0, -888, -888, -888, -888, 0, 0, 0, 0, 0, -888, -888, -888, -888, 0, -888, -888, -888, -888, 0, 0, 0, 0, -888, -888, -888, -888, -888, 0, 0, -888, -888, -888, -888, 0, -888, -888, -888, -888, -888, -888, -888, -888, -888, 0, 0, 0, -888, -888, 0, -888, 0, 0, 0, -888, -888, 0, -888, -888, -888, -888, // State 1156 - 0, 0, 0, 0, 0, 0, 0, 0, -619, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -345, 0, 0, 0, 0, 0, 0, -345, 0, -345, 0, 0, 0, -345, 0, 0, -345, 0, 0, 0, -345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -345, 0, -345, -345, -345, -345, 0, 0, 0, 0, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, -345, -345, -345, -345, 0, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, -345, -345, -345, -345, -345, 0, 0, 0, -345, -345, 0, -345, 0, 0, 0, -345, -345, 0, -345, -345, -345, -345, // State 1157 - 0, 0, 0, 0, 0, 0, 0, 0, -604, 0, 0, 0, 0, 0, 0, 1174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1158 - 0, 0, 0, 0, 0, 0, 0, 0, -609, 0, 0, 0, 0, 0, 0, 1175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1159 - 0, 0, 0, 0, 0, 0, 0, 0, -600, 0, 0, 0, 0, 0, 0, 1177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -620, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1160 - 0, 0, 0, 0, 0, 0, 0, 0, -576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -605, 0, 0, 0, 0, 0, 0, 1177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1161 - 0, 0, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -610, 0, 0, 0, 0, 0, 0, 1178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1162 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -601, 0, 0, 0, 0, 0, 0, 1180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1163 - 0, 0, 0, 0, 0, 0, 0, 0, -539, 0, 0, 0, 0, 0, 0, -539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1164 - 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1165 - 0, 0, 0, 0, 0, 0, 0, 0, 1178, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1166 - 0, 0, 0, 0, 0, 0, 0, 0, -547, 0, 0, 0, 0, 0, 0, -547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -540, 0, 0, 0, 0, 0, 0, -540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1167 - 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1168 - 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1181, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1169 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1170 - 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1171 - 0, 0, 0, 0, 0, 0, 0, 0, -610, 0, 0, 0, 0, 0, 0, 1181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1172 - 0, 0, 0, 0, 0, 0, 0, 0, -601, 0, 0, 0, 0, 0, 0, 1183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1173 - 0, 0, 0, 0, 0, 0, 0, 0, -577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1174 - 0, 0, 0, 0, 0, 0, 0, 0, -582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -611, 0, 0, 0, 0, 0, 0, 1184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1175 - 0, 0, 0, 0, 0, 0, 0, 0, -606, 0, 0, 0, 0, 0, 0, 1184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -602, 0, 0, 0, 0, 0, 0, 1186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1176 - 0, 0, 0, 0, 0, 0, 0, 0, -573, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1177 - 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1178 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -607, 0, 0, 0, 0, 0, 0, 1187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1179 - 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1180 - 0, 0, 0, 0, 0, 0, 0, 0, -583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1181 - 0, 0, 0, 0, 0, 0, 0, 0, -607, 0, 0, 0, 0, 0, 0, 1187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1182 - 0, 0, 0, 0, 0, 0, 0, 0, -574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1183 - 0, 0, 0, 0, 0, 0, 0, 0, -579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1184 - 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -608, 0, 0, 0, 0, 0, 0, 1190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1185 - 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1186 0, 0, 0, 0, 0, 0, 0, 0, -580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1187 + 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1188 + 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1189 + 0, 0, 0, 0, 0, 0, 0, 0, -581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; fn __action(state: i16, integer: usize) -> i16 { __ACTION[(state as usize) * 101 + integer] @@ -2535,27 +2544,27 @@ mod __parse__Top { // State 1 0, // State 2 - -768, + -769, // State 3 0, // State 4 0, // State 5 - -790, + -791, // State 6 -248, // State 7 -304, // State 8 - -883, + -882, // State 9 -155, // State 10 - -183, + -836, // State 11 -169, // State 12 - 0, + -837, // State 13 0, // State 14 @@ -2573,9 +2582,9 @@ mod __parse__Top { // State 20 0, // State 21 - -882, - // State 22 0, + // State 22 + -881, // State 23 0, // State 24 @@ -2587,15 +2596,15 @@ mod __parse__Top { // State 27 0, // State 28 - -303, - // State 29 0, + // State 29 + -303, // State 30 0, // State 31 - -426, - // State 32 0, + // State 32 + -426, // State 33 0, // State 34 @@ -2613,9 +2622,9 @@ mod __parse__Top { // State 40 0, // State 41 - -247, - // State 42 0, + // State 42 + -247, // State 43 0, // State 44 @@ -2673,11 +2682,11 @@ mod __parse__Top { // State 70 0, // State 71 - -154, + 0, // State 72 - -168, + -154, // State 73 - 0, + -168, // State 74 0, // State 75 @@ -2689,9 +2698,9 @@ mod __parse__Top { // State 78 0, // State 79 - -789, - // State 80 0, + // State 80 + -790, // State 81 0, // State 82 @@ -2973,9 +2982,9 @@ mod __parse__Top { // State 220 -432, // State 221 - -888, + -887, // State 222 - -892, + -891, // State 223 0, // State 224 @@ -3337,25 +3346,25 @@ mod __parse__Top { // State 402 0, // State 403 - -949, + -952, // State 404 - -943, + -946, // State 405 - -559, + -560, // State 406 -239, // State 407 - -765, + -766, // State 408 - -515, + -516, // State 409 - -839, + -840, // State 410 - -861, + -860, // State 411 -185, // State 412 - -866, + -865, // State 413 -159, // State 414 @@ -3363,19 +3372,19 @@ mod __parse__Top { // State 415 -427, // State 416 - -865, + -864, // State 417 -388, // State 418 - -878, + -877, // State 419 - -838, + -183, // State 420 - -840, + -839, // State 421 - -877, + -876, // State 422 - -550, + -551, // State 423 -349, // State 424 @@ -3393,17 +3402,17 @@ mod __parse__Top { // State 430 0, // State 431 - -520, + -521, // State 432 - -519, + -520, // State 433 - -518, + -519, // State 434 -430, // State 435 - -835, + -838, // State 436 - -558, + -559, // State 437 -158, // State 438 @@ -3433,7 +3442,7 @@ mod __parse__Top { // State 450 0, // State 451 - -884, + -883, // State 452 -90, // State 453 @@ -3443,7 +3452,7 @@ mod __parse__Top { // State 455 0, // State 456 - -841, + -895, // State 457 0, // State 458 @@ -3455,9 +3464,9 @@ mod __parse__Top { // State 461 0, // State 462 - -387, + -896, // State 463 - 0, + -387, // State 464 0, // State 465 @@ -3471,11 +3480,11 @@ mod __parse__Top { // State 469 0, // State 470 - -199, + 0, // State 471 - -816, + -199, // State 472 - 0, + -817, // State 473 0, // State 474 @@ -3487,9 +3496,9 @@ mod __parse__Top { // State 477 0, // State 478 - -187, - // State 479 0, + // State 479 + -187, // State 480 0, // State 481 @@ -3501,9 +3510,9 @@ mod __parse__Top { // State 484 0, // State 485 - -514, - // State 486 0, + // State 486 + -515, // State 487 0, // State 488 @@ -3517,23 +3526,23 @@ mod __parse__Top { // State 492 0, // State 493 - -204, - // State 494 0, + // State 494 + -204, // State 495 0, // State 496 - -366, - // State 497 0, + // State 497 + -366, // State 498 0, // State 499 - -314, + 0, // State 500 - -769, + -314, // State 501 - 0, + -770, // State 502 0, // State 503 @@ -3541,23 +3550,23 @@ mod __parse__Top { // State 504 0, // State 505 - -310, + 0, // State 506 - -313, + -310, // State 507 - 0, + -313, // State 508 - -308, - // State 509 0, + // State 509 + -308, // State 510 0, // State 511 0, // State 512 - -307, - // State 513 0, + // State 513 + -307, // State 514 0, // State 515 @@ -3567,19 +3576,19 @@ mod __parse__Top { // State 517 0, // State 518 - -311, - // State 519 0, + // State 519 + -311, // State 520 - -309, + 0, // State 521 - -312, + -309, // State 522 - 0, + -312, // State 523 - -774, - // State 524 0, + // State 524 + -775, // State 525 0, // State 526 @@ -3599,11 +3608,11 @@ mod __parse__Top { // State 533 0, // State 534 - -163, + 0, // State 535 - -242, + -163, // State 536 - 0, + -242, // State 537 0, // State 538 @@ -3613,27 +3622,27 @@ mod __parse__Top { // State 540 0, // State 541 - -764, + 0, // State 542 - -141, + -765, // State 543 - 0, + -141, // State 544 0, // State 545 - -348, + 0, // State 546 - -91, + -348, // State 547 - -551, + -91, // State 548 - 0, + -552, // State 549 - -860, + 0, // State 550 - -942, + -859, // State 551 - 0, + -945, // State 552 0, // State 553 @@ -3641,19 +3650,19 @@ mod __parse__Top { // State 554 0, // State 555 - -196, + 0, // State 556 - -190, + -196, // State 557 - -200, + -190, // State 558 - 0, + -200, // State 559 0, // State 560 - -186, - // State 561 0, + // State 561 + -186, // State 562 0, // State 563 @@ -3663,23 +3672,23 @@ mod __parse__Top { // State 565 0, // State 566 - -464, - // State 567 0, + // State 567 + -464, // State 568 - -203, - // State 569 0, + // State 569 + -203, // State 570 - -206, - // State 571 0, + // State 571 + -206, // State 572 0, // State 573 - -367, - // State 574 0, + // State 574 + -367, // State 575 0, // State 576 @@ -3721,9 +3730,9 @@ mod __parse__Top { // State 594 0, // State 595 - -772, - // State 596 0, + // State 596 + -773, // State 597 0, // State 598 @@ -3843,75 +3852,75 @@ mod __parse__Top { // State 655 0, // State 656 - -165, + 0, // State 657 - -162, - // State 658 0, + // State 658 + -165, // State 659 - 0, + -162, // State 660 0, // State 661 0, // State 662 - -241, + 0, // State 663 0, // State 664 - -142, + -241, // State 665 0, // State 666 - -201, + -142, // State 667 0, // State 668 - 0, + -201, // State 669 - -198, + 0, // State 670 0, // State 671 - -192, + -198, // State 672 0, // State 673 - 0, + -192, // State 674 - -189, + 0, // State 675 - -202, - // State 676 0, + // State 676 + -189, // State 677 - 0, + -202, // State 678 - -188, + 0, // State 679 0, // State 680 - 0, + -188, // State 681 - -462, + 0, // State 682 0, // State 683 - 0, + -462, // State 684 0, // State 685 0, // State 686 - -463, + 0, // State 687 - -205, + 0, // State 688 - -207, + -463, // State 689 - 0, + -205, // State 690 - 0, + -207, // State 691 0, // State 692 @@ -3923,11 +3932,11 @@ mod __parse__Top { // State 695 0, // State 696 - -773, + 0, // State 697 0, // State 698 - 0, + -774, // State 699 0, // State 700 @@ -3939,11 +3948,11 @@ mod __parse__Top { // State 703 0, // State 704 - -770, + 0, // State 705 0, // State 706 - 0, + -771, // State 707 0, // State 708 @@ -3997,11 +4006,11 @@ mod __parse__Top { // State 732 0, // State 733 - -164, + 0, // State 734 0, // State 735 - 0, + -164, // State 736 0, // State 737 @@ -4013,29 +4022,29 @@ mod __parse__Top { // State 740 0, // State 741 - -864, + 0, // State 742 0, // State 743 - 0, + -863, // State 744 - -194, + 0, // State 745 0, // State 746 - -195, + -194, // State 747 0, // State 748 - 0, + -195, // State 749 0, // State 750 - -461, + 0, // State 751 0, // State 752 - 0, + -461, // State 753 0, // State 754 @@ -4055,11 +4064,11 @@ mod __parse__Top { // State 761 0, // State 762 - -771, + 0, // State 763 0, // State 764 - 0, + -772, // State 765 0, // State 766 @@ -4069,11 +4078,11 @@ mod __parse__Top { // State 768 0, // State 769 - -270, + 0, // State 770 0, // State 771 - 0, + -270, // State 772 0, // State 773 @@ -4129,23 +4138,23 @@ mod __parse__Top { // State 798 0, // State 799 - -857, + 0, // State 800 0, // State 801 - -342, + -856, // State 802 - -346, - // State 803 0, + // State 803 + -342, // State 804 - 0, + -346, // State 805 - -921, + 0, // State 806 0, // State 807 - 0, + -924, // State 808 0, // State 809 @@ -4161,11 +4170,11 @@ mod __parse__Top { // State 814 0, // State 815 - -941, + 0, // State 816 0, // State 817 - 0, + -944, // State 818 0, // State 819 @@ -4195,13 +4204,13 @@ mod __parse__Top { // State 831 0, // State 832 - -197, + 0, // State 833 - -191, - // State 834 0, + // State 834 + -197, // State 835 - 0, + -191, // State 836 0, // State 837 @@ -4223,33 +4232,33 @@ mod __parse__Top { // State 845 0, // State 846 - -272, + 0, // State 847 0, // State 848 - 0, + -272, // State 849 0, // State 850 - -940, + 0, // State 851 - -266, + 0, // State 852 - -269, + -943, // State 853 - 0, + -266, // State 854 - 0, + -269, // State 855 0, // State 856 0, // State 857 - -414, + 0, // State 858 0, // State 859 - 0, + -414, // State 860 0, // State 861 @@ -4263,31 +4272,31 @@ mod __parse__Top { // State 865 0, // State 866 - -434, + 0, // State 867 0, // State 868 - 0, + -434, // State 869 0, // State 870 - -858, + 0, // State 871 0, // State 872 - -855, + -857, // State 873 - -343, - // State 874 0, + // State 874 + -854, // State 875 - 0, + -343, // State 876 - -347, + 0, // State 877 0, // State 878 - 0, + -347, // State 879 0, // State 880 @@ -4329,11 +4338,11 @@ mod __parse__Top { // State 898 0, // State 899 - -193, + 0, // State 900 0, // State 901 - 0, + -193, // State 902 0, // State 903 @@ -4349,33 +4358,33 @@ mod __parse__Top { // State 908 0, // State 909 - -268, + 0, // State 910 - -271, - // State 911 0, + // State 911 + -268, // State 912 - -416, + -271, // State 913 0, // State 914 - -406, + -416, // State 915 - -265, - // State 916 0, + // State 916 + -406, // State 917 - 0, + -265, // State 918 0, // State 919 0, // State 920 - -413, + 0, // State 921 0, // State 922 - 0, + -413, // State 923 0, // State 924 @@ -4387,11 +4396,11 @@ mod __parse__Top { // State 927 0, // State 928 - -400, + 0, // State 929 0, // State 930 - 0, + -400, // State 931 0, // State 932 @@ -4403,17 +4412,17 @@ mod __parse__Top { // State 935 0, // State 936 - -856, + 0, // State 937 0, // State 938 - -340, + -855, // State 939 - -893, - // State 940 0, + // State 940 + -340, // State 941 - 0, + -892, // State 942 0, // State 943 @@ -4421,11 +4430,11 @@ mod __parse__Top { // State 944 0, // State 945 - -859, + 0, // State 946 0, // State 947 - 0, + -858, // State 948 0, // State 949 @@ -4459,25 +4468,25 @@ mod __parse__Top { // State 963 0, // State 964 - -408, + 0, // State 965 - -267, - // State 966 0, + // State 966 + -408, // State 967 - -415, + -267, // State 968 0, // State 969 - -405, + -415, // State 970 - -398, + 0, // State 971 - -410, + -405, // State 972 - 0, + -398, // State 973 - 0, + -410, // State 974 0, // State 975 @@ -4499,15 +4508,15 @@ mod __parse__Top { // State 983 0, // State 984 - -431, + 0, // State 985 0, // State 986 - -498, + -431, // State 987 0, // State 988 - 0, + -499, // State 989 0, // State 990 @@ -4547,19 +4556,19 @@ mod __parse__Top { // State 1007 0, // State 1008 - -501, + 0, // State 1009 - -886, + -502, // State 1010 - -887, + -885, // State 1011 - -890, + -886, // State 1012 - -891, + -889, // State 1013 - -339, + -890, // State 1014 - 0, + -339, // State 1015 0, // State 1016 @@ -4573,9 +4582,9 @@ mod __parse__Top { // State 1020 0, // State 1021 - -920, - // State 1022 0, + // State 1022 + -923, // State 1023 0, // State 1024 @@ -4597,17 +4606,17 @@ mod __parse__Top { // State 1032 0, // State 1033 - -407, + 0, // State 1034 - -412, + -407, // State 1035 - -402, + -412, // State 1036 - 0, + -402, // State 1037 - -409, - // State 1038 0, + // State 1038 + -409, // State 1039 0, // State 1040 @@ -4621,13 +4630,13 @@ mod __parse__Top { // State 1044 0, // State 1045 - -433, + 0, // State 1046 - -107, + -433, // State 1047 - -499, + -107, // State 1048 - 0, + -500, // State 1049 0, // State 1050 @@ -4669,19 +4678,19 @@ mod __parse__Top { // State 1068 0, // State 1069 - -500, + 0, // State 1070 0, // State 1071 0, // State 1072 - -344, + -501, // State 1073 0, // State 1074 0, // State 1075 - 0, + -344, // State 1076 0, // State 1077 @@ -4703,17 +4712,17 @@ mod __parse__Top { // State 1085 0, // State 1086 - -404, + 0, // State 1087 - -411, + 0, // State 1088 - -401, - // State 1089 0, + // State 1089 + -404, // State 1090 - 0, + -411, // State 1091 - 0, + -401, // State 1092 0, // State 1093 @@ -4723,15 +4732,15 @@ mod __parse__Top { // State 1095 0, // State 1096 - -399, + 0, // State 1097 - -108, + 0, // State 1098 0, // State 1099 - 0, + -399, // State 1100 - 0, + -108, // State 1101 0, // State 1102 @@ -4777,27 +4786,27 @@ mod __parse__Top { // State 1122 0, // State 1123 - -341, + 0, // State 1124 0, // State 1125 0, // State 1126 - 0, + -341, // State 1127 0, // State 1128 0, // State 1129 - -403, + 0, // State 1130 - -397, + 0, // State 1131 0, // State 1132 - 0, + -403, // State 1133 - 0, + -397, // State 1134 0, // State 1135 @@ -4833,17 +4842,17 @@ mod __parse__Top { // State 1150 0, // State 1151 - -885, + 0, // State 1152 - -889, + 0, // State 1153 - -345, - // State 1154 0, + // State 1154 + -884, // State 1155 - 0, + -888, // State 1156 - 0, + -345, // State 1157 0, // State 1158 @@ -4904,609 +4913,615 @@ mod __parse__Top { 0, // State 1186 0, + // State 1187 + 0, + // State 1188 + 0, + // State 1189 + 0, ]; fn __goto(state: i16, nt: usize) -> i16 { match nt { 10 => match state { - 255 => 925, - 291 => 973, - 292 => 974, - 325 => 1038, - 357 => 1094, - 381 => 1135, - 382 => 1136, - 390 => 1156, - _ => 860, + 255 => 927, + 291 => 975, + 292 => 976, + 325 => 1039, + 358 => 1097, + 381 => 1138, + 382 => 1139, + 390 => 1159, + _ => 862, }, 13 => match state { - 90 => 683, - 137 => 748, - 138 => 749, - 197 => 834, - 239 => 905, - 279 => 960, - 280 => 961, - 316 => 1027, - _ => 563, + 91 => 685, + 137 => 750, + 138 => 751, + 197 => 836, + 239 => 907, + 279 => 962, + 280 => 963, + 316 => 1028, + _ => 564, }, 22 => match state { - 136 => 745, - 187 => 818, - 272 => 948, - _ => 554, + 136 => 747, + 187 => 820, + 272 => 950, + _ => 555, }, 25 => match state { - 188 => 821, - 273 => 950, - _ => 722, + 188 => 823, + 273 => 952, + _ => 724, }, - 29 => 712, - 35 => 579, + 29 => 714, + 35 => 580, 38 => 451, - 49 => 866, + 49 => 868, 53 => match state { - 70 | 105 => 112, + 71 | 106 => 113, _ => 3, }, - 56 => 73, + 56 => 74, 58 => match state { - 70 | 105 => 113, + 71 | 106 => 114, _ => 4, }, 63 => match state { - 341 => 372, - _ => 371, + 342 => 373, + _ => 372, }, 66 => match state { - 21 => 50, + 22 => 51, 224 => 268, 269 => 311, _ => 168, }, 71 => match state { - 116 => 177, - _ => 28, + 117 => 177, + _ => 29, }, 78 => match state { - 114 => 173, - 335 | 373 => 364, - _ => 23, + 115 => 173, + 335 | 374 => 365, + _ => 24, }, 79 => match state { - 342 | 386 => 1058, - _ => 987, + 343 | 386 => 1060, + _ => 989, }, 80 => match state { - 35 => 550, - 70 | 105 => 624, - 185 => 816, + 36 => 551, + 71 | 106 => 625, + 185 => 818, _ => 404, }, - 81 => 625, + 81 => 626, 82 => match state { 3 => 436, - 112 => 718, + 113 => 720, _ => 405, }, - 83 => 626, + 83 => 627, 84 => match state { - 106 => 708, - 115 => 720, - 146 => 763, - 151 => 768, - 204 => 845, + 107 => 710, + 116 => 722, + 146 => 765, + 151 => 770, + 204 => 847, _ => 441, }, 86 => match state { - 33 => 79, - 70 | 105 => 114, + 34 => 80, + 71 | 106 => 115, 180 => 228, _ => 5, }, - 87 => 627, - 88 => 988, - 89 => 498, + 87 => 628, + 88 => 990, + 89 => 499, 90 => match state { - 99 => 699, - 148 => 765, - _ => 581, + 100 => 701, + 148 => 767, + _ => 582, }, - 92 => 99, + 92 => 100, 94 => 406, - 95 => 628, + 95 => 629, 96 => match state { - 16 => 41, - 70 | 105 => 115, + 17 => 42, + 71 | 106 => 116, 124 => 191, _ => 6, }, - 97 => 629, + 97 => 630, 98 => match state { - 70 | 105 => 630, + 71 | 106 => 631, _ => 407, }, - 99 => 631, - 100 => 100, - 101 => 989, - 102 => 499, - 103 => 990, + 99 => 632, + 100 => 101, + 101 => 991, + 102 => 500, + 103 => 992, 104 => match state { - 360 => 1098, - 369 => 1112, - _ => 991, + 361 => 1101, + 370 => 1115, + _ => 993, }, 107 => match state { - 40 => 561, - 45 => 567, - 46 => 569, - 74 => 659, - 186 => 817, - 190 => 826, - 192 => 827, - 193 => 829, - _ => 551, + 41 => 562, + 46 => 568, + 47 => 570, + 75 => 661, + 186 => 819, + 190 => 828, + 192 => 829, + 193 => 831, + _ => 552, }, 109 => match state { - 28 | 177 => 78, - _ => 29, + 29 | 177 => 79, + _ => 30, }, 110 => 408, - 111 => 632, + 111 => 633, 112 => match state { - 224 => 881, - 269 => 943, - _ => 500, + 224 => 883, + 269 => 945, + _ => 501, }, 113 => match state { - 276 | 315 => 953, - _ => 898, + 276 | 315 => 955, + _ => 900, }, 115 => match state { 275 => 315, _ => 276, }, 116 => match state { - 51 => 577, - _ => 501, + 52 => 578, + _ => 502, }, - 118 => 51, - 119 => 502, + 118 => 52, + 119 => 503, 120 => match state { - 93 => 689, - _ => 486, + 94 => 691, + _ => 487, }, 121 => match state { 126 => 192, - 93 => 690, - _ => 45, + 94 => 692, + _ => 46, }, 122 => match state { - 126 => 730, - _ => 487, + 126 => 732, + _ => 488, }, 124 => match state { - 63 => 615, - 108 => 710, - 164 => 790, - _ => 607, + 64 => 616, + 109 => 712, + 164 => 792, + _ => 608, }, - 125 => 862, + 125 => 864, 127 => match state { - 221 => 873, - _ => 801, + 221 => 875, + _ => 803, }, 128 => 221, 129 => match state { - 222 => 876, - _ => 802, + 222 => 878, + _ => 804, }, 130 => 222, 131 => match state { - 21 | 50 | 110 | 152 | 162 | 168 | 171 | 184 | 205 | 209..=211 | 215 | 224 | 241..=242 | 244 | 246..=247 | 251 | 257 | 266..=269 | 283..=284 | 286 | 288..=290 | 299 | 305..=309 | 311..=312 | 321..=324 | 330..=331 | 344 | 351..=353 | 358..=359 | 367 | 376 | 378..=379 | 384 | 387..=389 => 52, - 70 | 105 => 116, - 14 => 471, - 29 => 542, - 38 => 558, - 47 => 571, - 58..=59 | 82 | 104 | 134 | 156 | 158 => 599, - 78 => 664, - 182 => 812, - 189 => 824, + 22 | 51 | 111 | 152 | 162 | 168 | 171 | 184 | 205 | 209..=211 | 215 | 224 | 241..=242 | 244 | 246..=247 | 251 | 257 | 266..=269 | 283..=284 | 286 | 288..=290 | 299 | 305..=309 | 311..=312 | 321..=324 | 330..=331 | 345 | 352..=354 | 359..=360 | 368 | 376 | 378..=379 | 384 | 387..=389 => 53, + 71 | 106 => 117, + 15 => 472, + 30 => 543, + 39 => 559, + 48 => 572, + 59..=60 | 83 | 105 | 134 | 156 | 158 => 600, + 79 => 666, + 182 => 814, + 189 => 826, _ => 7, }, - 132 => 633, + 132 => 634, 133 => match state { - 82 => 668, - 104 => 706, - 134 => 742, - _ => 604, + 83 => 670, + 105 => 708, + 134 => 744, + _ => 605, }, - 134 => 600, - 135 => 954, + 134 => 601, + 135 => 956, 136 => match state { - 156 | 158 => 781, - _ => 601, + 156 | 158 => 783, + _ => 602, }, - 137 => 503, + 137 => 504, 138 => match state { 144 => 202, _ => 142, }, 140 => 409, - 141 => 759, + 141 => 761, 142 => match state { - 142 => 755, - 144 => 760, - 202 => 841, - _ => 693, + 142 => 757, + 144 => 762, + 202 => 843, + _ => 695, }, 144 => match state { - 48 | 201 => 572, - _ => 494, + 49 | 201 => 573, + _ => 495, }, 146 => match state { 143 => 201, - _ => 48, + _ => 49, }, - 147 => 495, + 147 => 496, 148 => match state { - 12 => 462, - 27 => 541, - 34 => 549, - 120 => 721, - 176 => 808, - 181 => 811, + 13 => 463, + 28 => 542, + 35 => 550, + 120 => 723, + 176 => 810, + 181 => 813, _ => 410, }, - 149 => 634, - 150 => 504, - 151 => 505, - 152 => 506, + 149 => 635, + 150 => 505, + 151 => 506, + 152 => 507, 153 => match state { - 73 => 655, - _ => 532, + 74 => 657, + _ => 533, }, - 155 => 605, + 155 => 606, 156 => match state { 1 => 8, - 39 => 559, - 49 | 100..=101 => 574, - 67 => 621, - 157 => 782, - 208 => 849, - _ => 53, + 40 => 560, + 50 | 101..=102 => 575, + 68 => 622, + 157 => 784, + 208 => 851, + _ => 54, }, - 157 => 507, - 158 => 1050, + 157 => 508, + 158 => 1051, 159 => match state { - 56 => 106, 57 => 107, - 97 => 146, - 98 => 147, - 103 => 150, + 58 => 108, + 98 => 146, + 99 => 147, + 104 => 150, 145 => 203, - 13 | 15 | 19 | 26 | 54 | 62 | 64 | 69 | 83..=84 | 86 | 94 | 122..=123 | 126 | 128 | 130 | 135 | 165..=166 | 175 | 196 | 230..=231 | 235 | 260 | 271 | 298 | 313 | 346 | 368 => 463, - 17 | 87 | 91 | 140..=141 | 198..=200 | 236..=238 | 278 | 281 | 317..=319 | 348..=350 | 377 => 479, - 24 | 73 => 533, - 25 => 535, - 42..=43 | 137 | 239 | 279 => 564, - 61 | 65 => 612, - 68 => 622, - 70 | 105 => 635, - 153 | 249 => 770, - 155 | 253 | 256 | 293 | 295 | 326..=328 | 354..=356 | 380 | 383 | 391..=393 | 398..=401 => 774, - 159 | 218 => 783, - 160 => 787, - 161 => 788, - 163 => 789, - 174 => 806, - 212 => 854, - 213 => 855, - 216 | 291 | 357 | 381 => 861, - 217 => 863, - 219 => 865, - 258 => 929, - 259 | 297 => 930, - 261 => 934, - 302 | 338 | 341 | 360 | 366 | 369..=372 | 385 | 394 => 992, - 310 => 1014, - 329 => 1044, - 339 => 1054, - 342 | 386 => 1059, - 345 => 1073, - 361 | 396 => 1099, - 362 => 1105, - 363 => 1106, - 365 => 1108, - 375 => 1122, - 395 | 402 => 1162, - 397 => 1169, + 14 | 16 | 20 | 27 | 55 | 63 | 65 | 70 | 84..=85 | 87 | 95 | 122..=123 | 126 | 128 | 130 | 135 | 165..=166 | 175 | 196 | 230..=231 | 235 | 260 | 271 | 298 | 313 | 347 | 369 => 464, + 18 | 88 | 92 | 140..=141 | 198..=200 | 236..=238 | 278 | 281 | 317..=319 | 349..=351 | 377 => 480, + 25 | 74 => 534, + 26 => 536, + 43..=44 | 137 | 239 | 279 => 565, + 62 | 66 => 613, + 69 => 623, + 71 | 106 => 636, + 153 | 249 => 772, + 155 | 253 | 256 | 293 | 295 | 326..=328 | 355..=357 | 380 | 383 | 391..=393 | 398..=401 => 776, + 159 | 218 => 785, + 160 => 789, + 161 => 790, + 163 => 791, + 174 => 808, + 212 => 856, + 213 => 857, + 216 | 291 | 358 | 381 => 863, + 217 => 865, + 219 => 867, + 258 => 931, + 259 | 297 => 932, + 261 => 936, + 302 | 339 | 342 | 361 | 367 | 370..=373 | 385 | 394 => 994, + 310 => 1015, + 329 => 1045, + 340 => 1056, + 343 | 386 => 1061, + 346 => 1076, + 362 | 396 => 1102, + 363 => 1108, + 364 => 1109, + 366 => 1111, + 375 => 1125, + 395 | 402 => 1165, + 397 => 1172, _ => 411, }, - 160 => 508, - 163 => 784, + 160 => 509, + 163 => 786, 164 => match state { - 108 => 711, - _ => 608, + 109 => 713, + _ => 609, }, - 166 => 108, - 167 => 609, - 168 => 509, - 169 => 701, - 170 => 510, - 171 => 511, + 166 => 109, + 167 => 610, + 168 => 510, + 169 => 703, + 170 => 511, + 171 => 512, 172 => match state { - 253 => 922, - 256 => 926, - 293 => 975, - 295 => 978, - 326 => 1039, - 327 => 1040, - 328 => 1042, - 354 => 1089, - 355 => 1090, - 356 => 1092, - 380 => 1132, - 383 => 1137, - 391 => 1157, - 392 => 1158, - 393 => 1159, - 398 => 1171, - 399 => 1172, - 400 => 1175, - 401 => 1181, - _ => 775, + 253 => 924, + 256 => 928, + 293 => 977, + 295 => 980, + 326 => 1040, + 327 => 1041, + 328 => 1043, + 355 => 1092, + 356 => 1093, + 357 => 1095, + 380 => 1135, + 383 => 1140, + 391 => 1160, + 392 => 1161, + 393 => 1162, + 398 => 1174, + 399 => 1175, + 400 => 1178, + 401 => 1184, + _ => 777, }, 173 => match state { - 87 => 679, - 91 => 684, - 140 => 751, - 141 => 753, - 198 => 835, - 199 => 836, - 200 => 838, - 236 => 900, - 237 => 901, - 238 => 903, - 278 => 957, - 281 => 962, - 317 => 1028, - 318 => 1029, - 319 => 1030, - 348 => 1080, - 349 => 1081, + 88 => 681, + 92 => 686, + 140 => 753, + 141 => 755, + 198 => 837, + 199 => 838, + 200 => 840, + 236 => 902, + 237 => 903, + 238 => 905, + 278 => 959, + 281 => 964, + 317 => 1029, + 318 => 1030, + 319 => 1031, + 349 => 1083, 350 => 1084, - 377 => 1126, - _ => 480, + 351 => 1087, + 377 => 1129, + _ => 481, }, 174 => match state { - 70 | 105 => 636, + 71 | 106 => 637, _ => 412, }, 175 => match state { - 123 => 727, - _ => 472, + 123 => 729, + _ => 473, }, - 177 => 993, - 178 => 1060, - 179 => 994, + 177 => 995, + 178 => 1062, + 179 => 996, 180 => match state { - 262..=263 | 300 | 303 => 935, - _ => 985, + 262..=263 | 300 | 303 => 937, + _ => 987, }, 181 => match state { 263 => 304, 300 => 332, - 303 => 343, + 303 => 344, _ => 301, }, 182 => match state { - 395 | 402 => 1163, - _ => 1100, + 395 | 402 => 1166, + _ => 1103, }, 183 => match state { - 386 => 1147, - _ => 1061, + 386 => 1150, + _ => 1063, }, 184 => match state { - 342 | 386 => 1062, + 343 | 386 => 1064, _ => 333, }, 185 => match state { - 342 | 386 => 1063, + 343 | 386 => 1065, _ => 334, }, - 186 => 512, + 186 => 513, 187 => match state { 119 => 181, - _ => 34, + _ => 35, }, 188 => match state { - 13 | 122 => 464, - 84 | 231 => 672, - _ => 473, + 14 | 122 => 465, + 85 | 231 => 674, + _ => 474, }, - 189 => 465, + 189 => 466, 190 => match state { - 13 => 36, - 19 => 46, - 24 | 73 => 74, + 14 => 37, + 20 => 47, + 25 | 74 => 75, 122 => 186, 126 => 193, - 54 => 597, - 62 => 614, - 69 => 623, - 260 => 933, - 298 => 983, - 368 => 1111, - _ => 474, + 55 => 598, + 63 => 615, + 70 => 624, + 260 => 935, + 298 => 985, + 369 => 1114, + _ => 475, }, 191 => match state { - 84 => 136, + 85 => 136, 122 => 187, 231 => 272, - _ => 37, + _ => 38, }, - 192 => 513, + 192 => 514, 193 => match state { 4 => 437, - 18 => 485, - 113 => 719, - 125 => 729, + 19 => 486, + 114 => 721, + 125 => 731, _ => 413, }, - 194 => 637, + 194 => 638, 195 => match state { - 70 | 105 => 638, - 302 | 338 | 340..=342 | 360..=361 | 364 | 366 | 369..=372 | 385..=386 | 394 | 396 => 995, + 71 | 106 => 639, + 302 | 339 | 341..=343 | 361..=362 | 365 | 367 | 370..=373 | 385..=386 | 394 | 396 => 997, _ => 414, }, 196 => match state { - 340 => 1055, - 364 => 1107, - _ => 996, + 341 => 1057, + 365 => 1110, + _ => 998, }, 197 => match state { - 342 | 386 => 373, + 343 | 386 => 374, _ => 335, }, - 198 => 488, + 198 => 489, 199 => match state { - 58 => 602, - _ => 606, + 59 => 603, + _ => 607, }, 200 => match state { - 65 => 619, - _ => 613, + 66 => 620, + _ => 614, }, - 201 => 616, + 201 => 617, 202 => match state { - 218 => 864, - _ => 785, + 218 => 866, + _ => 787, }, 203 => match state { - 396 => 1165, - _ => 1101, + 396 => 1168, + _ => 1104, }, - 204 => 1064, - 205 => 776, - 206 => 481, - 207 => 1102, + 204 => 1066, + 205 => 778, + 206 => 482, + 207 => 1105, 208 => match state { - 122 => 723, - _ => 466, + 122 => 725, + _ => 467, }, 209 => 415, 210 => match state { - 19 | 126 => 489, - _ => 475, + 20 | 126 => 490, + _ => 476, }, - 211 => 771, - 212 => 997, + 211 => 773, + 212 => 999, 213 => match state { 195 => 234, 233 => 275, - 32 => 548, - 70 | 105 => 639, - 179 => 810, - 277 => 955, + 33 => 549, + 71 | 106 => 640, + 179 => 812, + 277 => 957, _ => 416, }, - 214 => 640, + 214 => 641, 215 => match state { - 155 => 777, - 253 => 923, - 293 | 328 | 354 | 356 | 380 | 392 | 398 | 400..=401 => 976, - _ => 927, + 155 => 779, + 253 => 925, + 293 | 328 | 355 | 357 | 380 | 392 | 398 | 400..=401 => 978, + _ => 929, }, 216 => match state { - 17 => 482, - 87 => 680, - 91 | 141 | 198..=199 | 237 | 281 | 317 | 319 | 349 => 685, - _ => 752, + 18 => 483, + 88 => 682, + 92 | 141 | 198..=199 | 237 | 281 | 317 | 319 | 350 => 687, + _ => 754, }, - 219 => 778, - 220 => 483, + 219 => 780, + 220 => 484, 224 => match state { - 147 => 764, - 150 => 767, - 154 => 773, - 203 => 844, - 206 => 847, - 207 => 848, - 240 => 908, - _ => 709, + 147 => 766, + 150 => 769, + 154 => 775, + 203 => 846, + 206 => 849, + 207 => 850, + 240 => 910, + _ => 711, }, - 225 => 514, + 225 => 515, 226 => match state { - 338 => 1052, - 341 => 1056, - 361 => 1103, - 366 => 1109, - 370 => 1113, - 371 => 1114, + 339 => 1054, + 342 => 1058, + 362 => 1106, + 367 => 1112, + 371 => 1116, 372 => 1117, - 385 => 1146, - 394 => 1161, - 396 => 1166, - _ => 998, + 373 => 1120, + 385 => 1149, + 394 => 1164, + 396 => 1169, + _ => 1000, }, 228 => match state { - 334 => 1049, - _ => 1048, + 334 => 1050, + _ => 1049, }, 229 => 336, 230 => 417, - 231 => 641, - 232 => 21, - 233 => 515, - 234 => 999, + 231 => 642, + 232 => 22, + 233 => 516, + 234 => 1001, 235 => match state { - 126 => 731, - _ => 490, + 126 => 733, + _ => 491, }, 236 => match state { - 22 => 71, - 70 | 105 => 117, + 23 => 72, + 71 | 106 => 118, 172 => 226, _ => 9, }, - 237 => 642, + 237 => 643, 238 => match state { - 117 => 180, - _ => 33, + 118 => 180, + _ => 34, }, 239 => match state { - 81 => 667, - _ => 552, + 82 => 669, + _ => 553, }, - 240 => 81, + 240 => 82, 241 => match state { - 129 => 737, - 131 => 739, - 194 => 831, - _ => 663, + 129 => 739, + 131 => 741, + 194 => 833, + _ => 665, }, 243 => match state { - 21 => 516, - 50 => 576, - 168 => 798, - 224 => 882, - 268 => 940, - 269 => 944, - 311 => 1018, - _ => 715, + 22 => 517, + 51 => 577, + 168 => 800, + 224 => 884, + 268 => 942, + 269 => 946, + 311 => 1019, + _ => 717, }, 244 => match state { - 13 | 84 | 122 | 231 => 467, - 15 | 19 | 26 | 64 | 83 | 86 | 94 | 123 | 126 | 128 | 130 | 135 | 165..=166 | 175 | 196 | 230 | 235 | 271 | 313 | 346 => 476, - 58..=59 | 82 | 104 | 134 | 156 | 158 => 603, + 14 | 85 | 122 | 231 => 468, + 16 | 20 | 27 | 65 | 84 | 87 | 95 | 123 | 126 | 128 | 130 | 135 | 165..=166 | 175 | 196 | 230 | 235 | 271 | 313 | 347 => 477, + 59..=60 | 83 | 105 | 134 | 156 | 158 => 604, _ => 418, }, - 245 => 1000, + 245 => 1002, 246 => match state { 291 => 325, - 357 => 382, + 358 => 382, 381 => 390, _ => 255, }, @@ -5514,226 +5529,229 @@ mod __parse__Top { 137 => 197, 239 => 280, 279 => 316, - 43 => 565, - _ => 90, + 44 => 566, + _ => 91, }, 250 => 269, 251 => match state { - 302 | 338 | 341 | 360..=361 | 366 | 369..=372 | 385 | 394 | 396 => 1001, - 337 => 1051, + 71 | 106 => 644, + 343 | 386 => 1067, _ => 419, }, - 252 => 337, - 253 => match state { - 10 | 118 | 374 => 456, + 252 => match state { + 302 | 339 | 342 | 361..=362 | 367 | 370..=373 | 385 | 394 | 396 => 337, + 337 => 1052, + 338 => 1053, _ => 420, }, - 254 => match state { - 70 | 105 => 118, - 342 | 386 => 374, + 253 => match state { + 10 => 456, + 12 => 462, _ => 10, }, + 254 => match state { + 128 => 738, + 130 => 740, + _ => 537, + }, 255 => match state { - 128 => 736, - 130 => 738, - _ => 536, + 175 => 809, + _ => 538, }, 256 => match state { - 175 => 807, - _ => 537, - }, - 257 => match state { 162 => 220, - 152 => 769, - 171 => 805, - 184 => 815, - 205 => 846, - 209 => 850, - 210 => 851, - 211 => 852, - 215 => 857, - 241 => 909, - 242 => 910, - 244 => 912, - 246 => 914, - 247 => 915, - 251 => 920, - 257 => 928, - 266 => 938, - 267 => 939, - 283 => 964, - 284 => 965, - 286 => 967, - 288 => 969, - 289 => 970, - 290 => 971, - 299 => 984, - 305 => 1009, - 306 => 1010, - 307 => 1011, - 308 => 1012, - 309 => 1013, - 312 => 1021, - 321 => 1033, - 322 => 1034, - 323 => 1035, - 324 => 1037, - 330 => 1045, - 331 => 1046, - 344 => 1072, - 351 => 1086, - 352 => 1087, - 353 => 1088, - 358 => 1096, - 359 => 1097, - 367 => 1110, - 376 => 1123, - 378 => 1129, - 379 => 1130, - 384 => 1140, - 387 => 1151, - 388 => 1152, - 389 => 1153, + 152 => 771, + 171 => 807, + 184 => 817, + 205 => 848, + 209 => 852, + 210 => 853, + 211 => 854, + 215 => 859, + 241 => 911, + 242 => 912, + 244 => 914, + 246 => 916, + 247 => 917, + 251 => 922, + 257 => 930, + 266 => 940, + 267 => 941, + 283 => 966, + 284 => 967, + 286 => 969, + 288 => 971, + 289 => 972, + 290 => 973, + 299 => 986, + 305 => 1010, + 306 => 1011, + 307 => 1012, + 308 => 1013, + 309 => 1014, + 312 => 1022, + 321 => 1034, + 322 => 1035, + 323 => 1036, + 324 => 1038, + 330 => 1046, + 331 => 1047, + 345 => 1075, + 352 => 1089, + 353 => 1090, + 354 => 1091, + 359 => 1099, + 360 => 1100, + 368 => 1113, + 376 => 1126, + 378 => 1132, + 379 => 1133, + 384 => 1143, + 387 => 1154, + 388 => 1155, + 389 => 1156, _ => 169, }, - 258 => match state { - 23 => 72, - 70 | 105 => 119, + 257 => match state { + 24 => 73, + 71 | 106 => 119, 173 => 227, _ => 11, }, - 259 => 643, - 260 => match state { - 77 => 131, - 102 => 148, + 258 => 645, + 259 => match state { + 78 => 131, + 103 => 148, 129 => 194, - 1 | 31 | 39 | 49 | 67 | 100..=101 | 157 | 208 | 294 => 421, - 13 => 468, - 15 | 24 | 54 | 62 | 64 | 69 | 73 | 83 | 86 | 94 | 123 | 135 | 165..=166 | 196 | 230 | 235 | 260 | 271 | 298 | 313 | 346 | 368 => 477, - 19 | 126 => 491, - 26 | 128 | 130 | 175 => 538, - 44 => 566, - 55 => 598, - 66 => 620, - 70 | 105 | 183 | 229 | 232 | 274 | 314 | 347 => 644, - 75 => 660, - 76 => 661, - 80 => 665, - 84 => 673, - 85 => 676, - 88 => 681, - 89 => 682, - 92 => 686, - 93 => 691, - 95 => 692, - 122 => 724, - 127 => 735, - 132 => 740, - 133 => 741, - 139 => 750, - 149 => 766, - 167 => 797, - 170 => 804, - 214 => 856, - 223 | 264 => 880, - 225 => 883, - 231 => 890, - 243 => 911, - 245 => 913, - 248 => 916, - 250 => 919, - 252 => 921, - 254 => 924, - 265 => 937, - 270 => 946, - 282 => 963, - 285 => 966, - 287 => 968, - 296 => 980, - 320 => 1032, - _ => 517, + 1 | 32 | 40 | 50 | 68 | 101..=102 | 157 | 208 | 294 => 421, + 14 => 469, + 16 | 25 | 55 | 63 | 65 | 70 | 74 | 84 | 87 | 95 | 123 | 135 | 165..=166 | 196 | 230 | 235 | 260 | 271 | 298 | 313 | 347 | 369 => 478, + 20 | 126 => 492, + 27 | 128 | 130 | 175 => 539, + 45 => 567, + 56 => 599, + 67 => 621, + 71 | 106 | 183 | 229 | 232 | 274 | 314 | 348 => 646, + 76 => 662, + 77 => 663, + 81 => 667, + 85 => 675, + 86 => 678, + 89 => 683, + 90 => 684, + 93 => 688, + 94 => 693, + 96 => 694, + 122 => 726, + 127 => 737, + 132 => 742, + 133 => 743, + 139 => 752, + 149 => 768, + 167 => 799, + 170 => 806, + 214 => 858, + 223 | 264 => 882, + 225 => 885, + 231 => 892, + 243 => 913, + 245 => 915, + 248 => 918, + 250 => 921, + 252 => 923, + 254 => 926, + 265 => 939, + 270 => 948, + 282 => 965, + 285 => 968, + 287 => 970, + 296 => 982, + 320 => 1033, + _ => 518, }, - 262 => 645, - 265 => match state { - 100 => 700, + 261 => 647, + 264 => match state { 101 => 702, - _ => 96, + 102 => 704, + _ => 97, }, - 266 => match state { - 31 => 547, - 294 => 977, + 265 => match state { + 32 => 548, + 294 => 979, _ => 422, }, - 268 => match state { - 15 => 40, + 267 => match state { + 16 => 41, 123 => 190, - 19 | 126 => 492, - 64 => 617, - 83 | 196 | 230 | 313 => 670, - 86 | 94 => 677, - 135 | 235 | 271 | 346 => 743, - 165 => 791, - 166 => 794, - _ => 539, + 20 | 126 => 493, + 65 => 618, + 84 | 196 | 230 | 313 => 672, + 87 | 95 => 679, + 135 | 235 | 271 | 347 => 745, + 165 => 793, + 166 => 796, + _ => 540, }, - 269 => 403, - 270 => 518, - 271 => 1002, + 268 => 403, + 269 => 519, + 270 => 338, + 271 => 12, 272 => 1003, - 273 => 540, - 274 => 618, - 275 => 111, - 276 => 519, - 277 => match state { - 249 => 917, - _ => 772, - }, + 273 => 1004, + 274 => 541, + 275 => 619, + 276 => 112, + 277 => 520, 278 => match state { - 107 => 154, + 249 => 919, + _ => 774, + }, + 279 => match state { + 108 => 154, 146 => 204, 147 => 206, 150 => 207, 203 => 240, - 111 => 717, + 112 => 719, _ => 151, }, - 280 => 779, - 281 => match state { - 70 | 105 => 120, - _ => 12, + 281 => 781, + 282 => match state { + 71 | 106 => 120, + _ => 13, }, - 282 => 484, - 283 => 1004, - 284 => 520, - 285 => match state { - 70 | 105 => 121, - 229 | 274 | 347 => 886, - _ => 813, + 283 => 485, + 284 => 1005, + 285 => 521, + 286 => match state { + 71 | 106 => 121, + 229 | 274 | 348 => 888, + _ => 815, }, - 286 => 646, - 287 => match state { + 287 => 648, + 288 => match state { 122 => 188, 231 => 273, - 70 | 105 => 647, - _ => 814, + 71 | 106 => 649, + _ => 816, }, - 288 => match state { - 105 => 707, - _ => 648, + 289 => match state { + 106 => 709, + _ => 650, }, - 290 => 521, - 291 => match state { - 30 => 545, - 70 | 105 => 649, - 178 => 809, + 291 => 522, + 292 => match state { + 31 => 546, + 71 | 106 => 651, + 178 => 811, _ => 423, }, - 292 => 650, - 293 => match state { - 13 => 469, - 49 | 100..=101 => 575, - 122 => 725, - _ => 522, + 293 => 652, + 294 => match state { + 14 => 470, + 50 | 101..=102 => 576, + 122 => 727, + _ => 523, }, _ => 0, } @@ -8975,7 +8993,7 @@ mod __parse__Top { 474 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 178, + nonterminal_produced: 177, } } 475 => { @@ -9015,95 +9033,95 @@ mod __parse__Top { } } 481 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 178, + } + } + 482 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 179, } } - 482 => { + 483 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 179, } } - 483 => { + 484 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 179, } } - 484 => { + 485 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 179, } } - 485 => { + 486 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 179, } } - 486 => { + 487 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 179, } } - 487 => { + 488 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 179, } } - 488 => { + 489 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 180, } } - 489 => { + 490 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 180, } } - 490 => { + 491 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 181, } } - 491 => { + 492 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 181, } } - 492 => { + 493 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 182, } } - 493 => { + 494 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 183, } } - 494 => { + 495 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 184, } } - 495 => { - __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 185, - } - } 496 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, @@ -9112,13 +9130,13 @@ mod __parse__Top { } 497 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 186, + states_to_pop: 3, + nonterminal_produced: 185, } } 498 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, + states_to_pop: 7, nonterminal_produced: 186, } } @@ -9130,14 +9148,14 @@ mod __parse__Top { } 500 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, + states_to_pop: 8, nonterminal_produced: 186, } } 501 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 187, + states_to_pop: 7, + nonterminal_produced: 186, } } 502 => { @@ -9166,20 +9184,20 @@ mod __parse__Top { } 506 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 188, + states_to_pop: 1, + nonterminal_produced: 187, } } 507 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 189, + states_to_pop: 3, + nonterminal_produced: 188, } } 508 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 190, + nonterminal_produced: 189, } } 509 => { @@ -9191,7 +9209,7 @@ mod __parse__Top { 510 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 191, + nonterminal_produced: 190, } } 511 => { @@ -9202,38 +9220,38 @@ mod __parse__Top { } 512 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 192, + states_to_pop: 1, + nonterminal_produced: 191, } } 513 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 193, + nonterminal_produced: 192, } } 514 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 193, } } 515 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 194, + states_to_pop: 1, + nonterminal_produced: 193, } } 516 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 194, } } 517 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 195, + nonterminal_produced: 194, } } 518 => { @@ -9251,1713 +9269,1713 @@ mod __parse__Top { 520 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 196, + nonterminal_produced: 195, } } 521 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 197, + nonterminal_produced: 196, } } 522 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 197, } } 523 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 197, + } + } + 524 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 198, } } - 524 => { + 525 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 198, } } - 525 => { + 526 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 199, } } - 526 => { + 527 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 199, } } - 527 => { + 528 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 200, } } - 528 => { + 529 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 200, } } - 529 => { + 530 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 201, } } - 530 => { + 531 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 201, } } - 531 => { + 532 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 201, } } - 532 => { + 533 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 201, } } - 533 => { + 534 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 202, } } - 534 => { + 535 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 202, } } - 535 => { + 536 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 202, } } - 536 => { + 537 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 202, } } - 537 => { + 538 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 203, } } - 538 => { + 539 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 203, } } - 539 => { + 540 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 204, } } - 540 => { + 541 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 204, } } - 541 => { + 542 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 205, } } - 542 => { + 543 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 205, } } - 543 => { + 544 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 206, } } - 544 => { + 545 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 206, } } - 545 => { + 546 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 207, } } - 546 => { + 547 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 207, } } - 547 => { + 548 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 208, } } - 548 => { + 549 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 208, } } - 549 => { + 550 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 209, } } - 550 => { + 551 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 209, } } - 551 => { + 552 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 210, } } - 552 => { + 553 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 210, } } - 553 => { + 554 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 211, } } - 554 => { + 555 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 211, } } - 555 => { + 556 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 212, } } - 556 => { + 557 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 212, } } - 557 => { + 558 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 213, } } - 558 => { + 559 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 213, } } - 559 => { + 560 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 214, } } - 560 => { + 561 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 214, } } - 561 => { + 562 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 215, } } - 562 => { + 563 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 215, } } - 563 => { + 564 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 216, } } - 564 => { + 565 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 216, } } - 565 => { + 566 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 217, } } - 566 => { + 567 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 217, } } - 567 => { + 568 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 217, } } - 568 => { + 569 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 218, } } - 569 => { + 570 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 218, } } - 570 => { + 571 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 218, } } - 571 => { + 572 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 572 => { + 573 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 219, } } - 573 => { + 574 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, nonterminal_produced: 219, } } - 574 => { + 575 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 575 => { + 576 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 576 => { + 577 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 219, } } - 577 => { + 578 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 578 => { + 579 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, nonterminal_produced: 219, } } - 579 => { + 580 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 11, nonterminal_produced: 219, } } - 580 => { + 581 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 581 => { + 582 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 219, } } - 582 => { + 583 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, nonterminal_produced: 219, } } - 583 => { + 584 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 584 => { + 585 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 585 => { + 586 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 586 => { + 587 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 587 => { + 588 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 588 => { + 589 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 589 => { + 590 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 590 => { + 591 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 591 => { + 592 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 219, } } - 592 => { + 593 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 593 => { + 594 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 594 => { + 595 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 595 => { + 596 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 219, } } - 596 => { + 597 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 597 => { + 598 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 598 => { + 599 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 599 => { + 600 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 600 => { + 601 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 219, } } - 601 => { + 602 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 602 => { + 603 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 603 => { + 604 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 604 => { + 605 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 605 => { + 606 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 219, } } - 606 => { + 607 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, nonterminal_produced: 219, } } - 607 => { + 608 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 608 => { + 609 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 609 => { + 610 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 219, } } - 610 => { + 611 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 611 => { + 612 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 612 => { + 613 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 613 => { + 614 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 219, } } - 614 => { + 615 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 615 => { + 616 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 616 => { + 617 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 617 => { + 618 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 618 => { + 619 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 219, } } - 619 => { + 620 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 620 => { + 621 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 621 => { + 622 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 622 => { + 623 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 219, } } - 623 => { + 624 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 219, } } - 624 => { + 625 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 625 => { + 626 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 626 => { + 627 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 627 => { + 628 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 219, } } - 628 => { + 629 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 219, } } - 629 => { + 630 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 630 => { + 631 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 631 => { + 632 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 632 => { + 633 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 633 => { + 634 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 219, } } - 634 => { + 635 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 635 => { + 636 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 219, } } - 636 => { + 637 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 219, } } - 637 => { + 638 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 638 => { + 639 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 219, } } - 639 => { + 640 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 640 => { + 641 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 219, } } - 641 => { + 642 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 219, } } - 642 => { + 643 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 219, } } - 643 => { + 644 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 219, } } - 644 => { + 645 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 219, } } - 645 => { + 646 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 219, } } - 646 => { + 647 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 219, } } - 647 => { + 648 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 219, } } - 648 => { + 649 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 219, } } - 649 => { + 650 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 650 => { + 651 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 220, } } - 651 => { + 652 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, nonterminal_produced: 220, } } - 652 => { + 653 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 653 => { + 654 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 654 => { + 655 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 220, } } - 655 => { + 656 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 656 => { + 657 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, nonterminal_produced: 220, } } - 657 => { + 658 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 11, nonterminal_produced: 220, } } - 658 => { + 659 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 659 => { + 660 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 220, } } - 660 => { + 661 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, nonterminal_produced: 220, } } - 661 => { + 662 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 662 => { + 663 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 663 => { + 664 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 664 => { + 665 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 665 => { + 666 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 666 => { + 667 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 667 => { + 668 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 668 => { + 669 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 669 => { + 670 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 220, } } - 670 => { + 671 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 671 => { + 672 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 672 => { + 673 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 673 => { + 674 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 220, } } - 674 => { + 675 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 675 => { + 676 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 676 => { + 677 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 677 => { + 678 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 678 => { + 679 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 220, } } - 679 => { + 680 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 680 => { + 681 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 681 => { + 682 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 682 => { + 683 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 683 => { + 684 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 220, } } - 684 => { + 685 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, nonterminal_produced: 220, } } - 685 => { + 686 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 686 => { + 687 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 687 => { + 688 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 9, nonterminal_produced: 220, } } - 688 => { + 689 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 689 => { + 690 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 690 => { + 691 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 691 => { + 692 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 220, } } - 692 => { + 693 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 693 => { + 694 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 694 => { + 695 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 695 => { + 696 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 696 => { + 697 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 8, nonterminal_produced: 220, } } - 697 => { + 698 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 698 => { + 699 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 699 => { + 700 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 700 => { + 701 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 220, } } - 701 => { + 702 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 220, } } - 702 => { + 703 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 703 => { + 704 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 704 => { + 705 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 705 => { + 706 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, nonterminal_produced: 220, } } - 706 => { + 707 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 220, } } - 707 => { + 708 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 708 => { + 709 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 709 => { + 710 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 710 => { + 711 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 711 => { + 712 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 220, } } - 712 => { + 713 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 713 => { + 714 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 220, } } - 714 => { + 715 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 220, } } - 715 => { + 716 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 716 => { + 717 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 220, } } - 717 => { + 718 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 718 => { + 719 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 220, } } - 719 => { + 720 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 220, } } - 720 => { + 721 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 220, } } - 721 => { + 722 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 220, } } - 722 => { + 723 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 220, } } - 723 => { + 724 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 220, } } - 724 => { + 725 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 220, } } - 725 => { + 726 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 220, } } - 726 => { + 727 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 220, } } - 727 => { + 728 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 221, } } - 728 => { + 729 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, nonterminal_produced: 221, } } - 729 => { + 730 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 222, } } - 730 => { + 731 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 222, } } - 731 => { + 732 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 222, } } - 732 => { + 733 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 222, } } - 733 => { + 734 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 222, } } - 734 => { + 735 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 222, } } - 735 => { + 736 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 222, } } - 736 => { + 737 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 222, } } - 737 => { + 738 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 223, } } - 738 => { + 739 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 223, } } - 739 => { + 740 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 223, } } - 740 => { + 741 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 223, } } - 741 => { + 742 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 223, } } - 742 => { + 743 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 223, } } - 743 => { + 744 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 223, } } - 744 => { + 745 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 223, } } - 745 => { + 746 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 224, } } - 746 => { + 747 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 224, } } - 747 => { + 748 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 225, } } - 748 => { + 749 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 226, } } - 749 => { + 750 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 226, } } - 750 => { + 751 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 227, } } - 751 => { + 752 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, nonterminal_produced: 227, } } - 752 => { + 753 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 228, } } - 753 => { + 754 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 228, } } - 754 => { + 755 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 228, } } - 755 => { + 756 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 228, } } - 756 => { + 757 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 228, } } - 757 => { + 758 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 228, } } - 758 => { + 759 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 228, } } - 759 => { + 760 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 229, } } - 760 => { + 761 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 229, } } - 761 => { + 762 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 229, } } - 762 => { + 763 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 229, } } - 763 => { + 764 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 230, } } - 764 => { + 765 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 230, } } - 765 => { + 766 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 231, } } - 766 => { + 767 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 231, } } - 767 => { + 768 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, nonterminal_produced: 232, } } - 768 => { + 769 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 232, } } - 769 => { + 770 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 232, } } - 770 => { + 771 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 232, } } - 771 => { + 772 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 232, } } - 772 => { + 773 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 232, } } - 773 => { + 774 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 232, } } - 774 => { + 775 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 233, } } - 775 => { + 776 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 233, } } - 776 => { + 777 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 233, } } - 777 => { + 778 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 234, } } - 778 => { + 779 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 234, } } - 779 => { + 780 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 234, } } - 780 => { + 781 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 234, } } - 781 => { + 782 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 234, } } - 782 => { + 783 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 234, } } - 783 => { + 784 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 234, } } - 784 => { + 785 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 234, } } - 785 => { + 786 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 234, } } - 786 => { + 787 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 235, } } - 787 => { + 788 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 235, } } - 788 => { + 789 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 236, } } - 789 => { + 790 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 236, } } - 790 => { + 791 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 237, } } - 791 => { + 792 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 237, } } - 792 => { + 793 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 238, } } - 793 => { + 794 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 238, } } - 794 => { + 795 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 239, } } - 795 => { + 796 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, nonterminal_produced: 239, } } - 796 => { + 797 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 239, } } - 797 => { + 798 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 239, } } - 798 => { + 799 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 240, } } - 799 => { + 800 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 240, } } - 800 => { + 801 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 241, } } - 801 => { + 802 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 241, } } - 802 => { + 803 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 242, } } - 803 => { + 804 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, nonterminal_produced: 242, } } - 804 => { - __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 243, - } - } 805 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, @@ -11019,141 +11037,141 @@ mod __parse__Top { } } 815 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 243, + } + } + 816 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 244, } } - 816 => { + 817 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 245, } } - 817 => { + 818 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 246, } } - 818 => { + 819 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 246, } } - 819 => { + 820 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 247, } } - 820 => { + 821 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, nonterminal_produced: 247, } } - 821 => { + 822 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 248, } } - 822 => { + 823 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 249, } } - 823 => { + 824 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, nonterminal_produced: 249, } } - 824 => { + 825 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 250, } } - 825 => { + 826 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 250, } } - 826 => { + 827 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 250, } } - 827 => { + 828 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 250, } } - 828 => { + 829 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 250, } } - 829 => { + 830 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, nonterminal_produced: 250, } } - 830 => { + 831 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 250, } } - 831 => { + 832 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, nonterminal_produced: 250, } } - 832 => { + 833 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, nonterminal_produced: 250, } } - 833 => { + 834 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, nonterminal_produced: 250, } } - 834 => { - __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 251, - } - } 835 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 252, + nonterminal_produced: 251, } } 836 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 252, + states_to_pop: 1, + nonterminal_produced: 251, } } 837 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 253, + nonterminal_produced: 252, } } 838 => { @@ -11165,61 +11183,61 @@ mod __parse__Top { 839 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 254, + nonterminal_produced: 253, } } 840 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 254, } } 841 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 255, + states_to_pop: 4, + nonterminal_produced: 254, } } 842 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 255, + states_to_pop: 3, + nonterminal_produced: 254, } } 843 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 255, + nonterminal_produced: 254, } } 844 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 255, + states_to_pop: 2, + nonterminal_produced: 254, } } 845 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 255, + states_to_pop: 3, + nonterminal_produced: 254, } } 846 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 255, + states_to_pop: 2, + nonterminal_produced: 254, } } 847 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 255, + nonterminal_produced: 254, } } 848 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 255, + states_to_pop: 1, + nonterminal_produced: 254, } } 849 => { @@ -11230,92 +11248,92 @@ mod __parse__Top { } 850 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 256, + states_to_pop: 2, + nonterminal_produced: 255, } } 851 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 256, + nonterminal_produced: 255, } } 852 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 256, + states_to_pop: 1, + nonterminal_produced: 255, } } 853 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 256, } } 854 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 257, + states_to_pop: 4, + nonterminal_produced: 256, } } 855 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 257, + states_to_pop: 2, + nonterminal_produced: 256, } } 856 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 257, + states_to_pop: 3, + nonterminal_produced: 256, } } 857 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 257, + states_to_pop: 4, + nonterminal_produced: 256, } } 858 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 3, nonterminal_produced: 257, } } 859 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 258, + states_to_pop: 1, + nonterminal_produced: 257, } } 860 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 258, } } 861 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 259, + states_to_pop: 1, + nonterminal_produced: 258, } } 862 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 5, nonterminal_produced: 259, } } 863 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 260, + states_to_pop: 1, + nonterminal_produced: 259, } } 864 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 260, + nonterminal_produced: 259, } } 865 => { @@ -11326,26 +11344,26 @@ mod __parse__Top { } 866 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 261, + states_to_pop: 0, + nonterminal_produced: 260, } } 867 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 5, nonterminal_produced: 261, } } 868 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 262, + states_to_pop: 1, + nonterminal_produced: 261, } } 869 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 262, + nonterminal_produced: 261, } } 870 => { @@ -11362,20 +11380,20 @@ mod __parse__Top { } 872 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 264, + states_to_pop: 0, + nonterminal_produced: 263, } } 873 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 264, } } 874 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 265, + nonterminal_produced: 264, } } 875 => { @@ -11387,7 +11405,7 @@ mod __parse__Top { 876 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 266, + nonterminal_produced: 265, } } 877 => { @@ -11405,103 +11423,103 @@ mod __parse__Top { 879 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 268, + nonterminal_produced: 267, } } 880 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 268, } } 881 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 269, + nonterminal_produced: 268, } } 882 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 269, + states_to_pop: 3, + nonterminal_produced: 268, } } 883 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 10, nonterminal_produced: 269, } } 884 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 270, + states_to_pop: 7, + nonterminal_produced: 269, } } 885 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 270, + nonterminal_produced: 269, } } 886 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 270, + states_to_pop: 4, + nonterminal_produced: 269, } } 887 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 270, + states_to_pop: 10, + nonterminal_produced: 269, } } 888 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 270, + states_to_pop: 7, + nonterminal_produced: 269, } } 889 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 270, + nonterminal_produced: 269, } } 890 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 270, + states_to_pop: 4, + nonterminal_produced: 269, } } 891 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 270, + states_to_pop: 6, + nonterminal_produced: 269, } } 892 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, + states_to_pop: 2, nonterminal_produced: 270, } } 893 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 271, + states_to_pop: 2, + nonterminal_produced: 270, } } 894 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 271, } } 895 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 272, + states_to_pop: 2, + nonterminal_produced: 271, } } 896 => { @@ -11513,7 +11531,7 @@ mod __parse__Top { 897 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 273, + nonterminal_produced: 272, } } 898 => { @@ -11525,7 +11543,7 @@ mod __parse__Top { 899 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 274, + nonterminal_produced: 273, } } 900 => { @@ -11536,74 +11554,74 @@ mod __parse__Top { } 901 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 275, + states_to_pop: 3, + nonterminal_produced: 274, } } 902 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 276, + states_to_pop: 3, + nonterminal_produced: 275, } } 903 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 276, + states_to_pop: 3, + nonterminal_produced: 275, } } 904 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 277, + states_to_pop: 1, + nonterminal_produced: 276, } } 905 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 5, nonterminal_produced: 277, } } 906 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 4, nonterminal_produced: 277, } } 907 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 277, + states_to_pop: 3, + nonterminal_produced: 278, } } 908 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 1, nonterminal_produced: 278, } } 909 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 278, } } 910 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 279, + states_to_pop: 2, + nonterminal_produced: 278, } } 911 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 4, nonterminal_produced: 279, } } 912 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 280, + nonterminal_produced: 279, } } 913 => { @@ -11614,13 +11632,13 @@ mod __parse__Top { } 914 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 281, + states_to_pop: 0, + nonterminal_produced: 280, } } 915 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 281, } } @@ -11639,37 +11657,37 @@ mod __parse__Top { 918 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 283, + nonterminal_produced: 282, } } 919 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 284, + states_to_pop: 1, + nonterminal_produced: 282, } } 920 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 284, + states_to_pop: 1, + nonterminal_produced: 283, } } 921 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 285, + nonterminal_produced: 284, } } 922 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 7, nonterminal_produced: 285, } } 923 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 286, + states_to_pop: 4, + nonterminal_produced: 285, } } 924 => { @@ -11680,153 +11698,171 @@ mod __parse__Top { } 925 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 287, + states_to_pop: 1, + nonterminal_produced: 286, } } 926 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 288, + states_to_pop: 1, + nonterminal_produced: 287, } } 927 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 288, + states_to_pop: 1, + nonterminal_produced: 287, } } 928 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, + states_to_pop: 3, nonterminal_produced: 288, } } 929 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 288, + nonterminal_produced: 289, } } 930 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 288, + states_to_pop: 3, + nonterminal_produced: 289, } } 931 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 288, + states_to_pop: 6, + nonterminal_produced: 289, } } 932 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 288, + states_to_pop: 4, + nonterminal_produced: 289, } } 933 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 288, + states_to_pop: 7, + nonterminal_produced: 289, } } 934 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 288, + states_to_pop: 5, + nonterminal_produced: 289, } } 935 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 288, + states_to_pop: 5, + nonterminal_produced: 289, } } 936 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 288, + states_to_pop: 3, + nonterminal_produced: 289, } } 937 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 288, + states_to_pop: 6, + nonterminal_produced: 289, } } 938 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 4, nonterminal_produced: 289, } } 939 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 290, + states_to_pop: 1, + nonterminal_produced: 289, } } 940 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 290, + states_to_pop: 2, + nonterminal_produced: 289, } } 941 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 291, + states_to_pop: 1, + nonterminal_produced: 290, } } 942 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 5, nonterminal_produced: 291, } } 943 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 292, + states_to_pop: 4, + nonterminal_produced: 291, } } 944 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 292, } } 945 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 293, + states_to_pop: 1, + nonterminal_produced: 292, } } 946 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 293, } } 947 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 293, } } - 948 => __state_machine::SimulatedReduce::Accept, + 948 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 294, + } + } 949 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 295, + nonterminal_produced: 294, } } 950 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 294, + } + } + 951 => __state_machine::SimulatedReduce::Accept, + 952 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 296, + } + } + 953 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, - nonterminal_produced: 295, + nonterminal_produced: 296, } } _ => panic!("invalid reduction index {}", __reduce_index) @@ -11984,7 +12020,7 @@ mod __parse__Top { __reduce23(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 24 => { - // ("," >) = ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(966); + // ("," >) = ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(969); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -11993,7 +12029,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action966::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action969::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12001,7 +12037,7 @@ mod __parse__Top { (5, 14) } 25 => { - // ("," >) = ",", "*", ",", KwargParameter => ActionFn(967); + // ("," >) = ",", "*", ",", KwargParameter => ActionFn(970); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -12009,7 +12045,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action967::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action970::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12017,7 +12053,7 @@ mod __parse__Top { (4, 14) } 26 => { - // ("," >) = ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(968); + // ("," >) = ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(971); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -12027,7 +12063,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action968::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action971::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12035,7 +12071,7 @@ mod __parse__Top { (6, 14) } 27 => { - // ("," >) = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(969); + // ("," >) = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(972); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -12044,7 +12080,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action969::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action972::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12052,14 +12088,14 @@ mod __parse__Top { (5, 14) } 28 => { - // ("," >) = ",", "*", StarTypedParameter => ActionFn(970); + // ("," >) = ",", "*", StarTypedParameter => ActionFn(973); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant63(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action970::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action973::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12067,13 +12103,13 @@ mod __parse__Top { (3, 14) } 29 => { - // ("," >) = ",", "*" => ActionFn(971); + // ("," >) = ",", "*" => ActionFn(974); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action971::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action974::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12081,7 +12117,7 @@ mod __parse__Top { (2, 14) } 30 => { - // ("," >) = ",", "*", StarTypedParameter, ("," >)+ => ActionFn(972); + // ("," >) = ",", "*", StarTypedParameter, ("," >)+ => ActionFn(975); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant63(__symbols); @@ -12089,7 +12125,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action972::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action975::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12097,14 +12133,14 @@ mod __parse__Top { (4, 14) } 31 => { - // ("," >) = ",", "*", ("," >)+ => ActionFn(973); + // ("," >) = ",", "*", ("," >)+ => ActionFn(976); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action973::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action976::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12112,7 +12148,7 @@ mod __parse__Top { (3, 14) } 32 => { - // ("," >)? = ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(990); + // ("," >)? = ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(993); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -12121,7 +12157,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action990::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action993::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12129,7 +12165,7 @@ mod __parse__Top { (5, 15) } 33 => { - // ("," >)? = ",", "*", ",", KwargParameter => ActionFn(991); + // ("," >)? = ",", "*", ",", KwargParameter => ActionFn(994); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -12137,7 +12173,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action991::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action994::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12145,7 +12181,7 @@ mod __parse__Top { (4, 15) } 34 => { - // ("," >)? = ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(992); + // ("," >)? = ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(995); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -12155,7 +12191,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action992::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action995::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12163,7 +12199,7 @@ mod __parse__Top { (6, 15) } 35 => { - // ("," >)? = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(993); + // ("," >)? = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(996); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -12172,7 +12208,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action993::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action996::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12180,14 +12216,14 @@ mod __parse__Top { (5, 15) } 36 => { - // ("," >)? = ",", "*", StarTypedParameter => ActionFn(994); + // ("," >)? = ",", "*", StarTypedParameter => ActionFn(997); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant63(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action994::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action997::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12195,13 +12231,13 @@ mod __parse__Top { (3, 15) } 37 => { - // ("," >)? = ",", "*" => ActionFn(995); + // ("," >)? = ",", "*" => ActionFn(998); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action995::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action998::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12209,7 +12245,7 @@ mod __parse__Top { (2, 15) } 38 => { - // ("," >)? = ",", "*", StarTypedParameter, ("," >)+ => ActionFn(996); + // ("," >)? = ",", "*", StarTypedParameter, ("," >)+ => ActionFn(999); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant63(__symbols); @@ -12217,7 +12253,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action996::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action999::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12225,14 +12261,14 @@ mod __parse__Top { (4, 15) } 39 => { - // ("," >)? = ",", "*", ("," >)+ => ActionFn(997); + // ("," >)? = ",", "*", ("," >)+ => ActionFn(1000); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action997::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1000::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12243,7 +12279,7 @@ mod __parse__Top { __reduce40(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 41 => { - // ("," >) = ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1026); + // ("," >) = ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1029); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -12252,7 +12288,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1026::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1029::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12260,7 +12296,7 @@ mod __parse__Top { (5, 16) } 42 => { - // ("," >) = ",", "*", ",", KwargParameter => ActionFn(1027); + // ("," >) = ",", "*", ",", KwargParameter => ActionFn(1030); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -12268,7 +12304,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1027::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1030::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12276,7 +12312,7 @@ mod __parse__Top { (4, 16) } 43 => { - // ("," >) = ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1028); + // ("," >) = ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1031); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -12286,7 +12322,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1028::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1031::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12294,7 +12330,7 @@ mod __parse__Top { (6, 16) } 44 => { - // ("," >) = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1029); + // ("," >) = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1032); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -12303,7 +12339,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1029::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1032::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12311,14 +12347,14 @@ mod __parse__Top { (5, 16) } 45 => { - // ("," >) = ",", "*", StarUntypedParameter => ActionFn(1030); + // ("," >) = ",", "*", StarUntypedParameter => ActionFn(1033); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant63(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1030::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1033::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12326,13 +12362,13 @@ mod __parse__Top { (3, 16) } 46 => { - // ("," >) = ",", "*" => ActionFn(1031); + // ("," >) = ",", "*" => ActionFn(1034); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1031::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1034::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12340,7 +12376,7 @@ mod __parse__Top { (2, 16) } 47 => { - // ("," >) = ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1032); + // ("," >) = ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1035); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant63(__symbols); @@ -12348,7 +12384,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1032::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1035::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12356,14 +12392,14 @@ mod __parse__Top { (4, 16) } 48 => { - // ("," >) = ",", "*", ("," >)+ => ActionFn(1033); + // ("," >) = ",", "*", ("," >)+ => ActionFn(1036); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1033::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1036::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12371,7 +12407,7 @@ mod __parse__Top { (3, 16) } 49 => { - // ("," >)? = ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1050); + // ("," >)? = ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1053); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -12380,7 +12416,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1050::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1053::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12388,7 +12424,7 @@ mod __parse__Top { (5, 17) } 50 => { - // ("," >)? = ",", "*", ",", KwargParameter => ActionFn(1051); + // ("," >)? = ",", "*", ",", KwargParameter => ActionFn(1054); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -12396,7 +12432,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1051::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1054::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12404,7 +12440,7 @@ mod __parse__Top { (4, 17) } 51 => { - // ("," >)? = ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1052); + // ("," >)? = ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1055); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -12414,7 +12450,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1052::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1055::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12422,7 +12458,7 @@ mod __parse__Top { (6, 17) } 52 => { - // ("," >)? = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1053); + // ("," >)? = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1056); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -12431,7 +12467,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1053::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1056::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12439,14 +12475,14 @@ mod __parse__Top { (5, 17) } 53 => { - // ("," >)? = ",", "*", StarUntypedParameter => ActionFn(1054); + // ("," >)? = ",", "*", StarUntypedParameter => ActionFn(1057); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant63(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1054::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1057::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12454,13 +12490,13 @@ mod __parse__Top { (3, 17) } 54 => { - // ("," >)? = ",", "*" => ActionFn(1055); + // ("," >)? = ",", "*" => ActionFn(1058); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1055::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1058::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12468,7 +12504,7 @@ mod __parse__Top { (2, 17) } 55 => { - // ("," >)? = ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1056); + // ("," >)? = ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1059); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant63(__symbols); @@ -12476,7 +12512,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1056::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1059::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12484,14 +12520,14 @@ mod __parse__Top { (4, 17) } 56 => { - // ("," >)? = ",", "*", ("," >)+ => ActionFn(1057); + // ("," >)? = ",", "*", ("," >)+ => ActionFn(1060); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1057::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1060::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12811,14 +12847,14 @@ mod __parse__Top { __reduce160(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 161 => { - // Arguments = "(", FunctionArgument, ")" => ActionFn(1537); + // Arguments = "(", FunctionArgument, ")" => ActionFn(1541); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant31(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1537::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1541::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12826,13 +12862,13 @@ mod __parse__Top { (3, 84) } 162 => { - // Arguments = "(", ")" => ActionFn(1538); + // Arguments = "(", ")" => ActionFn(1542); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1538::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1542::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12840,7 +12876,7 @@ mod __parse__Top { (2, 84) } 163 => { - // Arguments = "(", ( ",")+, FunctionArgument, ")" => ActionFn(1539); + // Arguments = "(", ( ",")+, FunctionArgument, ")" => ActionFn(1543); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant31(__symbols); @@ -12848,7 +12884,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1539::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1543::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12856,14 +12892,14 @@ mod __parse__Top { (4, 84) } 164 => { - // Arguments = "(", ( ",")+, ")" => ActionFn(1540); + // Arguments = "(", ( ",")+, ")" => ActionFn(1544); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant32(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1540::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1544::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12889,14 +12925,14 @@ mod __parse__Top { __reduce170(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 171 => { - // AsPattern = OrPattern, "as", Identifier => ActionFn(1233); + // AsPattern = OrPattern, "as", Identifier => ActionFn(1236); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1233::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1236::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12934,16 +12970,7 @@ mod __parse__Top { __reduce181(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 182 => { - // Atom<"all"> = StringLiteralOrFString+ => ActionFn(1236); - let __sym0 = __pop_Variant95(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = match super::__action1236::<>(source_code, mode, __sym0) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 94) + __reduce182(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 183 => { __reduce183(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) @@ -12967,7 +12994,7 @@ mod __parse__Top { __reduce189(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 190 => { - // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ",", ")" => ActionFn(1243); + // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ",", ")" => ActionFn(1245); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -12977,7 +13004,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1243::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1245::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -12985,7 +13012,7 @@ mod __parse__Top { (6, 94) } 191 => { - // Atom<"all"> = "(", NamedOrStarExpr, ",", ")" => ActionFn(1244); + // Atom<"all"> = "(", NamedOrStarExpr, ",", ")" => ActionFn(1246); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -12993,7 +13020,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1244::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1246::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13001,7 +13028,7 @@ mod __parse__Top { (4, 94) } 192 => { - // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1245); + // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1247); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -13012,7 +13039,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1245::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1247::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13020,7 +13047,7 @@ mod __parse__Top { (7, 94) } 193 => { - // Atom<"all"> = "(", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1246); + // Atom<"all"> = "(", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1248); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -13029,7 +13056,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1246::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1248::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13037,7 +13064,7 @@ mod __parse__Top { (5, 94) } 194 => { - // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ")" => ActionFn(1247); + // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ")" => ActionFn(1249); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant15(__symbols); @@ -13046,7 +13073,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1247::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1249::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13054,14 +13081,14 @@ mod __parse__Top { (5, 94) } 195 => { - // Atom<"all"> = "(", NamedOrStarExpr, ")" => ActionFn(1248); + // Atom<"all"> = "(", NamedOrStarExpr, ")" => ActionFn(1250); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1248::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1250::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13069,7 +13096,7 @@ mod __parse__Top { (3, 94) } 196 => { - // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ")" => ActionFn(1249); + // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ")" => ActionFn(1251); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant17(__symbols); @@ -13079,7 +13106,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1249::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1251::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13087,7 +13114,7 @@ mod __parse__Top { (6, 94) } 197 => { - // Atom<"all"> = "(", NamedOrStarExpr, ("," )+, ")" => ActionFn(1250); + // Atom<"all"> = "(", NamedOrStarExpr, ("," )+, ")" => ActionFn(1252); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant17(__symbols); @@ -13095,7 +13122,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1250::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1252::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13112,7 +13139,7 @@ mod __parse__Top { __reduce200(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 201 => { - // Atom<"all"> = "(", "**", Expression<"all">, ")" => ActionFn(1254); + // Atom<"all"> = "(", "**", Expression<"all">, ")" => ActionFn(1256); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant15(__symbols); @@ -13120,7 +13147,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1254::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1256::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13155,16 +13182,7 @@ mod __parse__Top { __reduce210(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 211 => { - // Atom<"no-withitems"> = StringLiteralOrFString+ => ActionFn(1263); - let __sym0 = __pop_Variant95(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = match super::__action1263::<>(source_code, mode, __sym0) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 95) + __reduce211(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 212 => { __reduce212(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) @@ -13182,7 +13200,7 @@ mod __parse__Top { __reduce216(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 217 => { - // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ",", ")" => ActionFn(1268); + // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ",", ")" => ActionFn(1269); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -13192,7 +13210,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1268::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1269::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13200,7 +13218,7 @@ mod __parse__Top { (6, 95) } 218 => { - // Atom<"no-withitems"> = "(", NamedOrStarExpr, ",", ")" => ActionFn(1269); + // Atom<"no-withitems"> = "(", NamedOrStarExpr, ",", ")" => ActionFn(1270); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -13208,7 +13226,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1269::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1270::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13216,7 +13234,7 @@ mod __parse__Top { (4, 95) } 219 => { - // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1270); + // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1271); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -13227,7 +13245,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1270::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1271::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13235,7 +13253,7 @@ mod __parse__Top { (7, 95) } 220 => { - // Atom<"no-withitems"> = "(", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1271); + // Atom<"no-withitems"> = "(", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1272); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -13244,7 +13262,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1271::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1272::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13252,7 +13270,7 @@ mod __parse__Top { (5, 95) } 221 => { - // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ")" => ActionFn(1272); + // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ")" => ActionFn(1273); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant15(__symbols); @@ -13261,7 +13279,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1272::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1273::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13269,14 +13287,14 @@ mod __parse__Top { (5, 95) } 222 => { - // Atom<"no-withitems"> = "(", NamedOrStarExpr, ")" => ActionFn(1273); + // Atom<"no-withitems"> = "(", NamedOrStarExpr, ")" => ActionFn(1274); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1273::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1274::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13284,7 +13302,7 @@ mod __parse__Top { (3, 95) } 223 => { - // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ")" => ActionFn(1274); + // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ")" => ActionFn(1275); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant17(__symbols); @@ -13294,7 +13312,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1274::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1275::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13302,7 +13320,7 @@ mod __parse__Top { (6, 95) } 224 => { - // Atom<"no-withitems"> = "(", NamedOrStarExpr, ("," )+, ")" => ActionFn(1275); + // Atom<"no-withitems"> = "(", NamedOrStarExpr, ("," )+, ")" => ActionFn(1276); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant17(__symbols); @@ -13310,7 +13328,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1275::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1276::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13327,7 +13345,7 @@ mod __parse__Top { __reduce227(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 228 => { - // Atom<"no-withitems"> = "(", "**", Expression<"all">, ")" => ActionFn(1279); + // Atom<"no-withitems"> = "(", "**", Expression<"all">, ")" => ActionFn(1280); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant15(__symbols); @@ -13335,7 +13353,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1279::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1280::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13727,11 +13745,11 @@ mod __parse__Top { __reduce356(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 357 => { - // ExpressionStatement = GenericList => ActionFn(1752); + // ExpressionStatement = GenericList => ActionFn(1756); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1752::<>(source_code, mode, __sym0) { + let __nt = match super::__action1756::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13739,13 +13757,13 @@ mod __parse__Top { (1, 137) } 358 => { - // ExpressionStatement = GenericList, AssignSuffix+ => ActionFn(1753); + // ExpressionStatement = GenericList, AssignSuffix+ => ActionFn(1757); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant17(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1753::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1757::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13753,14 +13771,14 @@ mod __parse__Top { (2, 137) } 359 => { - // ExpressionStatement = GenericList, AugAssign, TestListOrYieldExpr => ActionFn(1754); + // ExpressionStatement = GenericList, AugAssign, TestListOrYieldExpr => ActionFn(1758); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant49(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1754::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1758::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13768,7 +13786,7 @@ mod __parse__Top { (3, 137) } 360 => { - // ExpressionStatement = Test<"all">, ":", Test<"all">, AssignSuffix => ActionFn(1531); + // ExpressionStatement = Test<"all">, ":", Test<"all">, AssignSuffix => ActionFn(1535); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant15(__symbols); @@ -13776,7 +13794,7 @@ mod __parse__Top { let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1531::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1535::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13784,14 +13802,14 @@ mod __parse__Top { (4, 137) } 361 => { - // ExpressionStatement = Test<"all">, ":", Test<"all"> => ActionFn(1532); + // ExpressionStatement = Test<"all">, ":", Test<"all"> => ActionFn(1536); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1532::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1536::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13799,13 +13817,13 @@ mod __parse__Top { (3, 137) } 362 => { - // FStringConversion = "!", name => ActionFn(800); + // FStringConversion = "!", name => ActionFn(801); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant6(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action800::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action801::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -13843,15 +13861,15 @@ mod __parse__Top { __reduce372(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 373 => { - // FStringMiddlePattern = fstring_middle => ActionFn(803); + // FStringMiddlePattern = fstring_middle => ActionFn(1315); let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action803::<>(source_code, mode, __sym0) { + let __nt = match super::__action1315::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (1, 144) } 374 => { @@ -13867,25 +13885,25 @@ mod __parse__Top { __reduce377(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 378 => { - // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringConversion, FStringFormatSpecSuffix, "}" => ActionFn(1577); + // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringConversion, FStringFormatSpecSuffix, "}" => ActionFn(1581); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant44(__symbols); + let __sym4 = __pop_Variant70(__symbols); let __sym3 = __pop_Variant67(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1577::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1581::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (6, 147) } 379 => { - // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringConversion, "}" => ActionFn(1578); + // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringConversion, "}" => ActionFn(1582); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant67(__symbols); @@ -13894,32 +13912,32 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1578::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1582::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (5, 147) } 380 => { - // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringFormatSpecSuffix, "}" => ActionFn(1579); + // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringFormatSpecSuffix, "}" => ActionFn(1583); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant44(__symbols); + let __sym3 = __pop_Variant70(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1579::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1583::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (5, 147) } 381 => { - // FStringReplacementField = "{", TestListOrYieldExpr, "=", "}" => ActionFn(1580); + // FStringReplacementField = "{", TestListOrYieldExpr, "=", "}" => ActionFn(1584); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -13927,32 +13945,32 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1580::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1584::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (4, 147) } 382 => { - // FStringReplacementField = "{", TestListOrYieldExpr, FStringConversion, FStringFormatSpecSuffix, "}" => ActionFn(1581); + // FStringReplacementField = "{", TestListOrYieldExpr, FStringConversion, FStringFormatSpecSuffix, "}" => ActionFn(1585); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant44(__symbols); + let __sym3 = __pop_Variant70(__symbols); let __sym2 = __pop_Variant67(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1581::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1585::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (5, 147) } 383 => { - // FStringReplacementField = "{", TestListOrYieldExpr, FStringConversion, "}" => ActionFn(1582); + // FStringReplacementField = "{", TestListOrYieldExpr, FStringConversion, "}" => ActionFn(1586); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant67(__symbols); @@ -13960,42 +13978,42 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1582::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1586::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (4, 147) } 384 => { - // FStringReplacementField = "{", TestListOrYieldExpr, FStringFormatSpecSuffix, "}" => ActionFn(1583); + // FStringReplacementField = "{", TestListOrYieldExpr, FStringFormatSpecSuffix, "}" => ActionFn(1587); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant44(__symbols); + let __sym2 = __pop_Variant70(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1583::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1587::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (4, 147) } 385 => { - // FStringReplacementField = "{", TestListOrYieldExpr, "}" => ActionFn(1584); + // FStringReplacementField = "{", TestListOrYieldExpr, "}" => ActionFn(1588); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1584::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1588::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (3, 147) } 386 => { @@ -14200,11 +14218,11 @@ mod __parse__Top { __reduce452(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 453 => { - // IpyEscapeCommandExpr = ipy_escape_command => ActionFn(1342); + // IpyEscapeCommandExpr = ipy_escape_command => ActionFn(1344); let __sym0 = __pop_Variant5(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1342::<>(source_code, mode, __sym0) { + let __nt = match super::__action1344::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -14212,11 +14230,11 @@ mod __parse__Top { (1, 169) } 454 => { - // IpyEscapeCommandStatement = ipy_escape_command => ActionFn(1343); + // IpyEscapeCommandStatement = ipy_escape_command => ActionFn(1345); let __sym0 = __pop_Variant5(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1343::<>(source_code, mode, __sym0) { + let __nt = match super::__action1345::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -14224,13 +14242,13 @@ mod __parse__Top { (1, 170) } 455 => { - // IpyHelpEndEscapeCommandStatement = Expression<"all">, ("?")+ => ActionFn(1344); + // IpyHelpEndEscapeCommandStatement = Expression<"all">, ("?")+ => ActionFn(1346); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant22(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1344::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1346::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -14250,7 +14268,7 @@ mod __parse__Top { __reduce459(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 460 => { - // LambdaDef = "lambda", ParameterList, ":", fstring_middle, Test<"all"> => ActionFn(1781); + // LambdaDef = "lambda", ParameterList, ":", fstring_middle, Test<"all"> => ActionFn(1785); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant3(__symbols); @@ -14259,7 +14277,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1781::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1785::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -14267,7 +14285,7 @@ mod __parse__Top { (5, 174) } 461 => { - // LambdaDef = "lambda", ParameterList, ":", Test<"all"> => ActionFn(1782); + // LambdaDef = "lambda", ParameterList, ":", Test<"all"> => ActionFn(1786); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -14275,7 +14293,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1782::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1786::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -14283,7 +14301,7 @@ mod __parse__Top { (4, 174) } 462 => { - // LambdaDef = "lambda", ":", fstring_middle, Test<"all"> => ActionFn(1783); + // LambdaDef = "lambda", ":", fstring_middle, Test<"all"> => ActionFn(1787); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant3(__symbols); @@ -14291,7 +14309,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1783::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1787::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -14299,14 +14317,14 @@ mod __parse__Top { (4, 174) } 463 => { - // LambdaDef = "lambda", ":", Test<"all"> => ActionFn(1784); + // LambdaDef = "lambda", ":", Test<"all"> => ActionFn(1788); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1784::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1788::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; @@ -14341,20 +14359,20 @@ mod __parse__Top { __reduce472(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 473 => { - // LiteralPattern = StringLiteral+ => ActionFn(1351); - let __sym0 = __pop_Variant95(__symbols); + __reduce473(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 474 => { + // LiteralPattern = TwoOrMore => ActionFn(1354); + let __sym0 = __pop_Variant99(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1351::<>(source_code, mode, __sym0) { + let __nt = match super::__action1354::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 177) } - 474 => { - __reduce474(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } 475 => { __reduce475(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } @@ -14371,16 +14389,7 @@ mod __parse__Top { __reduce479(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 480 => { - // MappingKey = StringLiteralOrFString+ => ActionFn(1355); - let __sym0 = __pop_Variant95(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = match super::__action1355::<>(source_code, mode, __sym0) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); - (1, 178) + __reduce480(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 481 => { __reduce481(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) @@ -14653,7 +14662,10 @@ mod __parse__Top { __reduce570(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 571 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1603); + __reduce571(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 572 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1607); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant9(__symbols); @@ -14661,18 +14673,18 @@ mod __parse__Top { let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1603::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1607::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 572 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1604); + 573 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1608); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant9(__symbols); @@ -14682,18 +14694,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1604::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1608::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 219) } - 573 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1605); + 574 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1609); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); let __sym8 = __pop_Variant9(__symbols); @@ -14704,36 +14716,36 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1605::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1609::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (10, 219) } - 574 => { - // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter, "," => ActionFn(1606); + 575 => { + // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter, "," => ActionFn(1610); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1606::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1610::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 575 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter, "," => ActionFn(1607); + 576 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter, "," => ActionFn(1611); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant9(__symbols); @@ -14742,18 +14754,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1607::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1611::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 576 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter, "," => ActionFn(1608); + 577 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter, "," => ActionFn(1612); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant9(__symbols); @@ -14763,18 +14775,18 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1608::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1612::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 219) } - 577 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1609); + 578 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1613); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant9(__symbols); @@ -14783,18 +14795,18 @@ mod __parse__Top { let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1609::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1613::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 578 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1610); + 579 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1614); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); let __sym8 = __pop_Variant9(__symbols); @@ -14805,18 +14817,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1610::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1614::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (10, 219) } - 579 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1611); + 580 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1615); assert!(__symbols.len() >= 11); let __sym10 = __pop_Variant0(__symbols); let __sym9 = __pop_Variant9(__symbols); @@ -14828,18 +14840,18 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym10.2; - let __nt = match super::__action1611::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9, __sym10) { + let __nt = match super::__action1615::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9, __sym10) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (11, 219) } - 580 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1612); + 581 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1616); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant9(__symbols); @@ -14847,18 +14859,18 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1612::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1616::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 581 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1613); + 582 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1617); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant9(__symbols); @@ -14868,18 +14880,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1613::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1617::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 219) } - 582 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1614); + 583 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1618); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); let __sym8 = __pop_Variant9(__symbols); @@ -14890,35 +14902,35 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1614::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1618::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (10, 219) } - 583 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, "," => ActionFn(1615); + 584 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, "," => ActionFn(1619); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1615::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1619::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 584 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, "," => ActionFn(1616); + 585 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, "," => ActionFn(1620); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant63(__symbols); @@ -14926,18 +14938,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1616::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1620::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 585 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, "," => ActionFn(1617); + 586 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, "," => ActionFn(1621); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant63(__symbols); @@ -14946,52 +14958,52 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1617::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1621::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 586 => { - // ParameterList = OneOrMore>, ",", "*", "," => ActionFn(1618); + 587 => { + // ParameterList = OneOrMore>, ",", "*", "," => ActionFn(1622); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1618::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1622::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 587 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", "," => ActionFn(1619); + 588 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", "," => ActionFn(1623); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1619::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1623::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 588 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", "," => ActionFn(1620); + 589 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", "," => ActionFn(1624); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -14999,36 +15011,36 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1620::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1624::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 589 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1621); + 590 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1625); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant12(__symbols); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1621::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1625::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 590 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1622); + 591 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1626); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant12(__symbols); @@ -15037,18 +15049,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1622::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1626::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 591 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1623); + 592 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1627); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant12(__symbols); @@ -15058,35 +15070,35 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1623::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1627::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 219) } - 592 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, "," => ActionFn(1624); + 593 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, "," => ActionFn(1628); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1624::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1628::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 593 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, "," => ActionFn(1625); + 594 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, "," => ActionFn(1629); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant12(__symbols); @@ -15094,18 +15106,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1625::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1629::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 594 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, "," => ActionFn(1626); + 595 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, "," => ActionFn(1630); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant12(__symbols); @@ -15114,83 +15126,83 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1626::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1630::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 595 => { - // ParameterList = OneOrMore>, "," => ActionFn(1627); + 596 => { + // ParameterList = OneOrMore>, "," => ActionFn(1631); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1627::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1631::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 219) } - 596 => { - // ParameterList = OneOrMore>, ",", "/", "," => ActionFn(1628); + 597 => { + // ParameterList = OneOrMore>, ",", "/", "," => ActionFn(1632); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1628::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1632::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 597 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, "," => ActionFn(1629); + 598 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, "," => ActionFn(1633); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1629::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1633::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 598 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1630); + 599 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1634); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1630::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1634::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 599 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1631); + 600 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1635); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -15199,18 +15211,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1631::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1635::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 600 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1632); + 601 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1636); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); @@ -15220,35 +15232,35 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1632::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1636::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 219) } - 601 => { - // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter => ActionFn(1633); + 602 => { + // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter => ActionFn(1637); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1633::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1637::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 602 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter => ActionFn(1634); + 603 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter => ActionFn(1638); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -15256,18 +15268,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1634::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1638::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 603 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter => ActionFn(1635); + 604 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter => ActionFn(1639); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -15276,18 +15288,18 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1635::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1639::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 604 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1636); + 605 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1640); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -15295,18 +15307,18 @@ mod __parse__Top { let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1636::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1640::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 605 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1637); + 606 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1641); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); @@ -15316,18 +15328,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1637::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1641::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 219) } - 606 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1638); + 607 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1642); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant9(__symbols); let __sym8 = __pop_Variant0(__symbols); @@ -15338,36 +15350,36 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1638::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1642::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (10, 219) } - 607 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1639); + 608 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1643); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1639::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1643::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 608 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1640); + 609 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1644); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -15376,18 +15388,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1640::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1644::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 609 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1641); + 610 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1645); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); @@ -15397,52 +15409,52 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1641::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1645::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 219) } - 610 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter => ActionFn(1642); + 611 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter => ActionFn(1646); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1642::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1646::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 611 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter => ActionFn(1643); + 612 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter => ActionFn(1647); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant63(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1643::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1647::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 612 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter => ActionFn(1644); + 613 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter => ActionFn(1648); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant63(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -15450,85 +15462,85 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1644::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1648::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 613 => { - // ParameterList = OneOrMore>, ",", "*" => ActionFn(1645); + 614 => { + // ParameterList = OneOrMore>, ",", "*" => ActionFn(1649); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1645::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1649::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 219) } - 614 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*" => ActionFn(1646); + 615 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*" => ActionFn(1650); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1646::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1650::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 615 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*" => ActionFn(1647); + 616 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*" => ActionFn(1651); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1647::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1651::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 616 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1648); + 617 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1652); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant12(__symbols); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1648::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1652::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 617 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1649); + 618 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1653); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant63(__symbols); @@ -15536,18 +15548,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1649::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1653::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 618 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1650); + 619 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1654); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant12(__symbols); let __sym6 = __pop_Variant63(__symbols); @@ -15556,52 +15568,52 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1650::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1654::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 219) } - 619 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+ => ActionFn(1651); + 620 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+ => ActionFn(1655); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1651::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1655::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 620 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+ => ActionFn(1652); + 621 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+ => ActionFn(1656); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1652::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1656::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 621 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+ => ActionFn(1653); + 622 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+ => ActionFn(1657); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -15609,95 +15621,95 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1653::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1657::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 622 => { - // ParameterList = OneOrMore> => ActionFn(1654); - let __sym0 = __pop_Variant85(__symbols); + 623 => { + // ParameterList = OneOrMore> => ActionFn(1658); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1654::<>(source_code, mode, __sym0) { + let __nt = match super::__action1658::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (1, 219) } - 623 => { - // ParameterList = OneOrMore>, ",", "/" => ActionFn(1655); + 624 => { + // ParameterList = OneOrMore>, ",", "/" => ActionFn(1659); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1655::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1659::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 219) } - 624 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+ => ActionFn(1656); + 625 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+ => ActionFn(1660); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1656::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1660::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 625 => { - // ParameterList = OneOrMore>, ",", KwargParameter, "," => ActionFn(1657); + 626 => { + // ParameterList = OneOrMore>, ",", KwargParameter, "," => ActionFn(1661); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1657::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1661::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 626 => { - // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter, "," => ActionFn(1658); + 627 => { + // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter, "," => ActionFn(1662); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1658::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1662::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 627 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter, "," => ActionFn(1659); + 628 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter, "," => ActionFn(1663); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant9(__symbols); @@ -15705,68 +15717,68 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1659::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1663::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 219) } - 628 => { - // ParameterList = OneOrMore>, ",", KwargParameter => ActionFn(1660); + 629 => { + // ParameterList = OneOrMore>, ",", KwargParameter => ActionFn(1664); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1660::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1664::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 219) } - 629 => { - // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter => ActionFn(1661); + 630 => { + // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter => ActionFn(1665); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1661::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1665::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 630 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter => ActionFn(1662); + 631 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter => ActionFn(1666); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1662::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1666::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 631 => { - // ParameterList = "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1402); + 632 => { + // ParameterList = "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1404); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant9(__symbols); @@ -15775,15 +15787,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1402::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1404::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 632 => { - // ParameterList = "*", ",", KwargParameter, "," => ActionFn(1403); + 633 => { + // ParameterList = "*", ",", KwargParameter, "," => ActionFn(1405); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant9(__symbols); @@ -15791,15 +15803,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1403::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1405::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 633 => { - // ParameterList = "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1404); + 634 => { + // ParameterList = "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1406); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant9(__symbols); @@ -15809,15 +15821,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1404::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1406::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 219) } - 634 => { - // ParameterList = "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1405); + 635 => { + // ParameterList = "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1407); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant9(__symbols); @@ -15826,44 +15838,44 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1405::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1407::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 635 => { - // ParameterList = "*", StarTypedParameter, "," => ActionFn(1406); + 636 => { + // ParameterList = "*", StarTypedParameter, "," => ActionFn(1408); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1406::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1408::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 219) } - 636 => { - // ParameterList = "*", "," => ActionFn(1407); + 637 => { + // ParameterList = "*", "," => ActionFn(1409); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1407::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1409::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 219) } - 637 => { - // ParameterList = "*", StarTypedParameter, ("," >)+, "," => ActionFn(1408); + 638 => { + // ParameterList = "*", StarTypedParameter, ("," >)+, "," => ActionFn(1410); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant12(__symbols); @@ -15871,30 +15883,30 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1408::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1410::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 638 => { - // ParameterList = "*", ("," >)+, "," => ActionFn(1409); + 639 => { + // ParameterList = "*", ("," >)+, "," => ActionFn(1411); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1409::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1411::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 219) } - 639 => { - // ParameterList = "*", StarTypedParameter, ",", KwargParameter => ActionFn(1410); + 640 => { + // ParameterList = "*", StarTypedParameter, ",", KwargParameter => ActionFn(1412); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -15902,30 +15914,30 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1410::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1412::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 640 => { - // ParameterList = "*", ",", KwargParameter => ActionFn(1411); + 641 => { + // ParameterList = "*", ",", KwargParameter => ActionFn(1413); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1411::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1413::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 219) } - 641 => { - // ParameterList = "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1412); + 642 => { + // ParameterList = "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1414); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -15934,15 +15946,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1412::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1414::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 219) } - 642 => { - // ParameterList = "*", ("," >)+, ",", KwargParameter => ActionFn(1413); + 643 => { + // ParameterList = "*", ("," >)+, ",", KwargParameter => ActionFn(1415); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -15950,76 +15962,76 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1413::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1415::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 219) } - 643 => { - // ParameterList = "*", StarTypedParameter => ActionFn(1414); + 644 => { + // ParameterList = "*", StarTypedParameter => ActionFn(1416); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1414::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1416::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 219) } - 644 => { - // ParameterList = "*" => ActionFn(1415); + 645 => { + // ParameterList = "*" => ActionFn(1417); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1415::<>(source_code, mode, __sym0) { + let __nt = match super::__action1417::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (1, 219) } - 645 => { - // ParameterList = "*", StarTypedParameter, ("," >)+ => ActionFn(1416); + 646 => { + // ParameterList = "*", StarTypedParameter, ("," >)+ => ActionFn(1418); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1416::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1418::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 219) } - 646 => { - // ParameterList = "*", ("," >)+ => ActionFn(1417); + 647 => { + // ParameterList = "*", ("," >)+ => ActionFn(1419); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1417::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1419::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 219) } - 647 => { - __reduce647(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } 648 => { __reduce648(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 649 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1663); + __reduce649(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 650 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1667); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant9(__symbols); @@ -16027,18 +16039,18 @@ mod __parse__Top { let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1663::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1667::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 650 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1664); + 651 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1668); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant9(__symbols); @@ -16048,18 +16060,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1664::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1668::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 220) } - 651 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1665); + 652 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1669); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); let __sym8 = __pop_Variant9(__symbols); @@ -16070,36 +16082,36 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1665::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1669::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (10, 220) } - 652 => { - // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter, "," => ActionFn(1666); + 653 => { + // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter, "," => ActionFn(1670); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1666::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1670::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 653 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter, "," => ActionFn(1667); + 654 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter, "," => ActionFn(1671); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant9(__symbols); @@ -16108,18 +16120,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1667::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1671::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 654 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter, "," => ActionFn(1668); + 655 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter, "," => ActionFn(1672); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant9(__symbols); @@ -16129,18 +16141,18 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1668::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1672::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 220) } - 655 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1669); + 656 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1673); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant9(__symbols); @@ -16149,18 +16161,18 @@ mod __parse__Top { let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1669::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1673::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 656 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1670); + 657 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1674); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); let __sym8 = __pop_Variant9(__symbols); @@ -16171,18 +16183,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1670::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1674::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (10, 220) } - 657 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1671); + 658 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1675); assert!(__symbols.len() >= 11); let __sym10 = __pop_Variant0(__symbols); let __sym9 = __pop_Variant9(__symbols); @@ -16194,18 +16206,18 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym10.2; - let __nt = match super::__action1671::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9, __sym10) { + let __nt = match super::__action1675::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9, __sym10) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (11, 220) } - 658 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1672); + 659 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1676); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant9(__symbols); @@ -16213,18 +16225,18 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1672::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1676::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 659 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1673); + 660 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1677); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant9(__symbols); @@ -16234,18 +16246,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1673::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1677::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 220) } - 660 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1674); + 661 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1678); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); let __sym8 = __pop_Variant9(__symbols); @@ -16256,35 +16268,35 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1674::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1678::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (10, 220) } - 661 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, "," => ActionFn(1675); + 662 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, "," => ActionFn(1679); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1675::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1679::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 662 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, "," => ActionFn(1676); + 663 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, "," => ActionFn(1680); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant63(__symbols); @@ -16292,18 +16304,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1676::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1680::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 663 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, "," => ActionFn(1677); + 664 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, "," => ActionFn(1681); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant63(__symbols); @@ -16312,52 +16324,52 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1677::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1681::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 664 => { - // ParameterList = OneOrMore>, ",", "*", "," => ActionFn(1678); + 665 => { + // ParameterList = OneOrMore>, ",", "*", "," => ActionFn(1682); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1678::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1682::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 665 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", "," => ActionFn(1679); + 666 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", "," => ActionFn(1683); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1679::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1683::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 666 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", "," => ActionFn(1680); + 667 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", "," => ActionFn(1684); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -16365,36 +16377,36 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1680::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1684::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 667 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1681); + 668 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1685); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant12(__symbols); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1681::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1685::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 668 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1682); + 669 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1686); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant12(__symbols); @@ -16403,18 +16415,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1682::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1686::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 669 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1683); + 670 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1687); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant12(__symbols); @@ -16424,35 +16436,35 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1683::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1687::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 220) } - 670 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, "," => ActionFn(1684); + 671 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, "," => ActionFn(1688); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1684::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1688::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 671 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, "," => ActionFn(1685); + 672 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, "," => ActionFn(1689); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant12(__symbols); @@ -16460,18 +16472,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1685::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1689::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 672 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, "," => ActionFn(1686); + 673 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, "," => ActionFn(1690); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant12(__symbols); @@ -16480,83 +16492,83 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1686::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1690::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 673 => { - // ParameterList = OneOrMore>, "," => ActionFn(1687); + 674 => { + // ParameterList = OneOrMore>, "," => ActionFn(1691); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1687::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1691::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 220) } - 674 => { - // ParameterList = OneOrMore>, ",", "/", "," => ActionFn(1688); + 675 => { + // ParameterList = OneOrMore>, ",", "/", "," => ActionFn(1692); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1688::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1692::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 675 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, "," => ActionFn(1689); + 676 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, "," => ActionFn(1693); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1689::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1693::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 676 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1690); + 677 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1694); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1690::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1694::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 677 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1691); + 678 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1695); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -16565,18 +16577,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1691::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1695::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 678 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1692); + 679 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1696); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); @@ -16586,35 +16598,35 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1692::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1696::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 220) } - 679 => { - // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter => ActionFn(1693); + 680 => { + // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter => ActionFn(1697); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1693::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1697::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 680 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter => ActionFn(1694); + 681 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter => ActionFn(1698); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -16622,18 +16634,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1694::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1698::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 681 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter => ActionFn(1695); + 682 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter => ActionFn(1699); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -16642,18 +16654,18 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1695::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1699::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 682 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1696); + 683 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1700); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -16661,18 +16673,18 @@ mod __parse__Top { let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1696::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1700::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 683 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1697); + 684 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1701); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); @@ -16682,18 +16694,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1697::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1701::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 220) } - 684 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1698); + 685 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1702); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant9(__symbols); let __sym8 = __pop_Variant0(__symbols); @@ -16704,36 +16716,36 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1698::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1702::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (10, 220) } - 685 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1699); + 686 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1703); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1699::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1703::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 686 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1700); + 687 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1704); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -16742,18 +16754,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1700::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1704::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 687 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1701); + 688 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1705); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); @@ -16763,52 +16775,52 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1701::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1705::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (9, 220) } - 688 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter => ActionFn(1702); + 689 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter => ActionFn(1706); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1702::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1706::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 689 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter => ActionFn(1703); + 690 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter => ActionFn(1707); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant63(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1703::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1707::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 690 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter => ActionFn(1704); + 691 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter => ActionFn(1708); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant63(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -16816,85 +16828,85 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1704::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1708::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 691 => { - // ParameterList = OneOrMore>, ",", "*" => ActionFn(1705); + 692 => { + // ParameterList = OneOrMore>, ",", "*" => ActionFn(1709); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1705::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1709::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 220) } - 692 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*" => ActionFn(1706); + 693 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*" => ActionFn(1710); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1706::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1710::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 693 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*" => ActionFn(1707); + 694 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*" => ActionFn(1711); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1707::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1711::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 694 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1708); + 695 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1712); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant12(__symbols); let __sym3 = __pop_Variant63(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1708::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1712::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 695 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1709); + 696 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1713); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant63(__symbols); @@ -16902,18 +16914,18 @@ mod __parse__Top { let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1709::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1713::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 696 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1710); + 697 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1714); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant12(__symbols); let __sym6 = __pop_Variant63(__symbols); @@ -16922,52 +16934,52 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1710::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1714::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (8, 220) } - 697 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+ => ActionFn(1711); + 698 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+ => ActionFn(1715); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1711::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1715::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 698 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+ => ActionFn(1712); + 699 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+ => ActionFn(1716); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1712::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1716::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 699 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+ => ActionFn(1713); + 700 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+ => ActionFn(1717); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -16975,95 +16987,95 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1713::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1717::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 700 => { - // ParameterList = OneOrMore> => ActionFn(1714); - let __sym0 = __pop_Variant85(__symbols); + 701 => { + // ParameterList = OneOrMore> => ActionFn(1718); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1714::<>(source_code, mode, __sym0) { + let __nt = match super::__action1718::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (1, 220) } - 701 => { - // ParameterList = OneOrMore>, ",", "/" => ActionFn(1715); + 702 => { + // ParameterList = OneOrMore>, ",", "/" => ActionFn(1719); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1715::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1719::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 220) } - 702 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+ => ActionFn(1716); + 703 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+ => ActionFn(1720); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1716::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1720::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 703 => { - // ParameterList = OneOrMore>, ",", KwargParameter, "," => ActionFn(1717); + 704 => { + // ParameterList = OneOrMore>, ",", KwargParameter, "," => ActionFn(1721); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1717::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1721::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 704 => { - // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter, "," => ActionFn(1718); + 705 => { + // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter, "," => ActionFn(1722); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1718::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1722::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 705 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter, "," => ActionFn(1719); + 706 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter, "," => ActionFn(1723); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant9(__symbols); @@ -17071,68 +17083,68 @@ mod __parse__Top { let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1719::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1723::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (7, 220) } - 706 => { - // ParameterList = OneOrMore>, ",", KwargParameter => ActionFn(1720); + 707 => { + // ParameterList = OneOrMore>, ",", KwargParameter => ActionFn(1724); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1720::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1724::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 220) } - 707 => { - // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter => ActionFn(1721); + 708 => { + // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter => ActionFn(1725); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1721::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1725::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 708 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter => ActionFn(1722); + 709 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter => ActionFn(1726); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1722::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1726::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 709 => { - // ParameterList = "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1440); + 710 => { + // ParameterList = "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1442); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant9(__symbols); @@ -17141,15 +17153,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1440::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1442::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 710 => { - // ParameterList = "*", ",", KwargParameter, "," => ActionFn(1441); + 711 => { + // ParameterList = "*", ",", KwargParameter, "," => ActionFn(1443); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant9(__symbols); @@ -17157,15 +17169,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1441::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1443::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 711 => { - // ParameterList = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1442); + 712 => { + // ParameterList = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1444); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant9(__symbols); @@ -17175,15 +17187,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1442::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1444::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (6, 220) } - 712 => { - // ParameterList = "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1443); + 713 => { + // ParameterList = "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1445); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant9(__symbols); @@ -17192,44 +17204,44 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1443::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1445::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 713 => { - // ParameterList = "*", StarUntypedParameter, "," => ActionFn(1444); + 714 => { + // ParameterList = "*", StarUntypedParameter, "," => ActionFn(1446); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1444::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1446::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 220) } - 714 => { - // ParameterList = "*", "," => ActionFn(1445); + 715 => { + // ParameterList = "*", "," => ActionFn(1447); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1445::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1447::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 220) } - 715 => { - // ParameterList = "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1446); + 716 => { + // ParameterList = "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1448); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant12(__symbols); @@ -17237,30 +17249,30 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1446::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1448::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 716 => { - // ParameterList = "*", ("," >)+, "," => ActionFn(1447); + 717 => { + // ParameterList = "*", ("," >)+, "," => ActionFn(1449); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1447::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1449::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 220) } - 717 => { - // ParameterList = "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1448); + 718 => { + // ParameterList = "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1450); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -17268,30 +17280,30 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1448::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1450::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 718 => { - // ParameterList = "*", ",", KwargParameter => ActionFn(1449); + 719 => { + // ParameterList = "*", ",", KwargParameter => ActionFn(1451); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1449::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1451::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 220) } - 719 => { - // ParameterList = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1450); + 720 => { + // ParameterList = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1452); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -17300,15 +17312,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1450::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1452::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (5, 220) } - 720 => { - // ParameterList = "*", ("," >)+, ",", KwargParameter => ActionFn(1451); + 721 => { + // ParameterList = "*", ("," >)+, ",", KwargParameter => ActionFn(1453); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -17316,71 +17328,68 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1451::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1453::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (4, 220) } - 721 => { - // ParameterList = "*", StarUntypedParameter => ActionFn(1452); + 722 => { + // ParameterList = "*", StarUntypedParameter => ActionFn(1454); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1452::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1454::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 220) } - 722 => { - // ParameterList = "*" => ActionFn(1453); + 723 => { + // ParameterList = "*" => ActionFn(1455); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1453::<>(source_code, mode, __sym0) { + let __nt = match super::__action1455::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (1, 220) } - 723 => { - // ParameterList = "*", StarUntypedParameter, ("," >)+ => ActionFn(1454); + 724 => { + // ParameterList = "*", StarUntypedParameter, ("," >)+ => ActionFn(1456); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1454::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1456::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 220) } - 724 => { - // ParameterList = "*", ("," >)+ => ActionFn(1455); + 725 => { + // ParameterList = "*", ("," >)+ => ActionFn(1457); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1455::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1457::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 220) } - 725 => { - __reduce725(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } 726 => { __reduce726(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } @@ -17391,7 +17400,10 @@ mod __parse__Top { __reduce728(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 729 => { - // ParameterListStarArgs = "*", StarTypedParameter, ",", KwargParameter => ActionFn(891); + __reduce729(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 730 => { + // ParameterListStarArgs = "*", StarTypedParameter, ",", KwargParameter => ActionFn(892); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -17399,30 +17411,30 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action891::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action892::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (4, 222) } - 730 => { - // ParameterListStarArgs = "*", ",", KwargParameter => ActionFn(892); + 731 => { + // ParameterListStarArgs = "*", ",", KwargParameter => ActionFn(893); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action892::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action893::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (3, 222) } - 731 => { - // ParameterListStarArgs = "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(893); + 732 => { + // ParameterListStarArgs = "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(894); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -17431,15 +17443,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action893::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action894::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (5, 222) } - 732 => { - // ParameterListStarArgs = "*", ("," >)+, ",", KwargParameter => ActionFn(894); + 733 => { + // ParameterListStarArgs = "*", ("," >)+, ",", KwargParameter => ActionFn(895); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -17447,70 +17459,70 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action894::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action895::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (4, 222) } - 733 => { - // ParameterListStarArgs = "*", StarTypedParameter => ActionFn(895); + 734 => { + // ParameterListStarArgs = "*", StarTypedParameter => ActionFn(896); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action895::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action896::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (2, 222) } - 734 => { - // ParameterListStarArgs = "*" => ActionFn(896); + 735 => { + // ParameterListStarArgs = "*" => ActionFn(897); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action896::<>(source_code, mode, __sym0) { + let __nt = match super::__action897::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 222) } - 735 => { - // ParameterListStarArgs = "*", StarTypedParameter, ("," >)+ => ActionFn(897); + 736 => { + // ParameterListStarArgs = "*", StarTypedParameter, ("," >)+ => ActionFn(898); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action897::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action898::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (3, 222) } - 736 => { - // ParameterListStarArgs = "*", ("," >)+ => ActionFn(898); + 737 => { + // ParameterListStarArgs = "*", ("," >)+ => ActionFn(899); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action898::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action899::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (2, 222) } - 737 => { - // ParameterListStarArgs = "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1018); + 738 => { + // ParameterListStarArgs = "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1021); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -17518,30 +17530,30 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1018::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1021::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (4, 223) } - 738 => { - // ParameterListStarArgs = "*", ",", KwargParameter => ActionFn(1019); + 739 => { + // ParameterListStarArgs = "*", ",", KwargParameter => ActionFn(1022); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1019::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1022::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (3, 223) } - 739 => { - // ParameterListStarArgs = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1020); + 740 => { + // ParameterListStarArgs = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1023); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -17550,15 +17562,15 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1020::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1023::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (5, 223) } - 740 => { - // ParameterListStarArgs = "*", ("," >)+, ",", KwargParameter => ActionFn(1021); + 741 => { + // ParameterListStarArgs = "*", ("," >)+, ",", KwargParameter => ActionFn(1024); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -17566,100 +17578,97 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1021::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1024::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (4, 223) } - 741 => { - // ParameterListStarArgs = "*", StarUntypedParameter => ActionFn(1022); + 742 => { + // ParameterListStarArgs = "*", StarUntypedParameter => ActionFn(1025); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1022::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1025::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (2, 223) } - 742 => { - // ParameterListStarArgs = "*" => ActionFn(1023); + 743 => { + // ParameterListStarArgs = "*" => ActionFn(1026); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1023::<>(source_code, mode, __sym0) { + let __nt = match super::__action1026::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 223) } - 743 => { - // ParameterListStarArgs = "*", StarUntypedParameter, ("," >)+ => ActionFn(1024); + 744 => { + // ParameterListStarArgs = "*", StarUntypedParameter, ("," >)+ => ActionFn(1027); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1024::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1027::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (3, 223) } - 744 => { - // ParameterListStarArgs = "*", ("," >)+ => ActionFn(1025); + 745 => { + // ParameterListStarArgs = "*", ("," >)+ => ActionFn(1028); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1025::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1028::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (2, 223) } - 745 => { - // Parameters = "(", ParameterList, ")" => ActionFn(1458); + 746 => { + // Parameters = "(", ParameterList, ")" => ActionFn(1460); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant46(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1458::<>(source_code, mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1460::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (3, 224) } - 746 => { - // Parameters = "(", ")" => ActionFn(1459); + 747 => { + // Parameters = "(", ")" => ActionFn(1461); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1459::<>(source_code, mode, __sym0, __sym1) { + let __nt = match super::__action1461::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 224) } - 747 => { - __reduce747(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } 748 => { __reduce748(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } @@ -17919,25 +17928,34 @@ mod __parse__Top { __reduce833(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 834 => { - // StringLiteral = string => ActionFn(934); - let __sym0 = __pop_Variant7(__symbols); + __reduce834(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 835 => { + __reduce835(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 836 => { + // String = TwoOrMore => ActionFn(1493); + let __sym0 = __pop_Variant99(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action934::<>(source_code, mode, __sym0) { + let __nt = match super::__action1493::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant69(__nt), __end)); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); (1, 251) } - 835 => { - __reduce835(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 836 => { - __reduce836(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } 837 => { - __reduce837(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // StringLiteral = string => ActionFn(1494); + let __sym0 = __pop_Variant7(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = match super::__action1494::<>(source_code, mode, __sym0) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant69(__nt), __end)); + (1, 252) } 838 => { __reduce838(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) @@ -18270,18 +18288,27 @@ mod __parse__Top { __reduce947(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 948 => { + __reduce948(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 949 => { + __reduce949(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 950 => { + __reduce950(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 951 => { // __Top = Top => ActionFn(0); - let __sym0 = __pop_Variant96(__symbols); + let __sym0 = __pop_Variant98(__symbols); let __start = __sym0.0; let __end = __sym0.2; let __nt = super::__action0::<>(source_code, mode, __sym0); return Some(Ok(__nt)); } - 949 => { - __reduce949(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 952 => { + __reduce952(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } - 950 => { - __reduce950(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 953 => { + __reduce953(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } _ => panic!("invalid action code {}", __action) }; @@ -18329,20 +18356,20 @@ mod __parse__Top { fn __pop_Variant59< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (Option>, ast::ParenthesizedExpr), TextSize) + ) -> (TextSize, (Option>, crate::parser::ParenthesizedExpr), TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant59(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant76< + fn __pop_Variant79< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (Option, Option), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant76(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant79(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18376,60 +18403,60 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant27< + fn __pop_Variant29< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (TextSize, ast::ParenthesizedExpr, ast::Suite), TextSize) + ) -> (TextSize, (TextSize, ast::Suite), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant27(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant29(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant29< + fn __pop_Variant27< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (TextSize, ast::Suite), TextSize) + ) -> (TextSize, (TextSize, crate::parser::ParenthesizedExpr, ast::Suite), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant29(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant27(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant87< + fn __pop_Variant90< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (Vec, Vec), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant87(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant90(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } fn __pop_Variant42< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (ast::CmpOp, ast::ParenthesizedExpr), TextSize) + ) -> (TextSize, (ast::CmpOp, crate::parser::ParenthesizedExpr), TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant42(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant80< + fn __pop_Variant83< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (ast::Expr, ast::Pattern), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant80(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant83(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } fn __pop_Variant39< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (ast::ParenthesizedExpr, ast::Identifier), TextSize) + ) -> (TextSize, (crate::parser::ParenthesizedExpr, ast::Identifier), TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant39(__v), __r)) => (__l, __v, __r), @@ -18439,7 +18466,7 @@ mod __parse__Top { fn __pop_Variant60< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize) + ) -> (TextSize, (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr), TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant60(__v), __r)) => (__l, __v, __r), @@ -18486,13 +18513,13 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant92< + fn __pop_Variant95< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, Option, TextSize) + ) -> (TextSize, Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant92(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant95(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18539,70 +18566,70 @@ mod __parse__Top { fn __pop_Variant61< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize) + ) -> (TextSize, Vec<(Option>, crate::parser::ParenthesizedExpr)>, TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant61(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant84< + fn __pop_Variant87< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant84(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant87(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant73< + fn __pop_Variant99< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, Vec, TextSize) + ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant73(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant99(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant54< + fn __pop_Variant76< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, Vec, TextSize) + ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant54(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant76(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant82< + fn __pop_Variant54< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, Vec, TextSize) + ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant82(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant54(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } fn __pop_Variant85< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, Vec, TextSize) + ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant85(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant33< + fn __pop_Variant88< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, Vec, TextSize) + ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant33(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant88(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18616,33 +18643,33 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant83< + fn __pop_Variant86< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant83(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant86(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant94< + fn __pop_Variant97< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant94(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant97(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant86< + fn __pop_Variant89< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant86(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant89(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18656,6 +18683,16 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } + fn __pop_Variant33< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, Vec, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant33(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant32< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -18669,7 +18706,7 @@ mod __parse__Top { fn __pop_Variant28< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize) + ) -> (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant28(__v), __r)) => (__l, __v, __r), @@ -18679,7 +18716,7 @@ mod __parse__Top { fn __pop_Variant43< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize) + ) -> (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant43(__v), __r)) => (__l, __v, __r), @@ -18696,23 +18733,13 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant95< - >( - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec, TextSize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant95(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } - fn __pop_Variant91< + fn __pop_Variant94< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant91(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant94(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18736,23 +18763,23 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant70< + fn __pop_Variant73< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec, TextSize) + ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant70(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant73(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant78< + fn __pop_Variant81< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant78(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant81(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18766,16 +18793,6 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant17< - >( - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec, TextSize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant17(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } fn __pop_Variant36< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -18806,6 +18823,16 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } + fn __pop_Variant17< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, alloc::vec::Vec, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant17(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant22< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -18816,23 +18843,23 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant75< + fn __pop_Variant78< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant75(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant78(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant72< + fn __pop_Variant75< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Alias, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant72(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant75(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18856,13 +18883,13 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant90< + fn __pop_Variant93< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Comprehension, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant90(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant93(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18896,6 +18923,26 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } + fn __pop_Variant72< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, ast::FStringElement, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant72(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant70< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, ast::FStringFormatSpec, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant70(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant23< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -18906,33 +18953,33 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant77< + fn __pop_Variant80< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::MatchCase, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant77(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant80(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant96< + fn __pop_Variant98< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Mod, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant96(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant98(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant81< + fn __pop_Variant84< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Number, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant81(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant84(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18976,16 +19023,6 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant15< - >( - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, ast::ParenthesizedExpr, TextSize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant15(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } fn __pop_Variant35< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -18996,23 +19033,23 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant89< + fn __pop_Variant92< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::PatternArguments, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant89(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant92(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant79< + fn __pop_Variant82< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::PatternKeyword, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant79(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant82(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -19036,33 +19073,33 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant97< + fn __pop_Variant100< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::TypeParam, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant97(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant100(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant98< + fn __pop_Variant101< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::TypeParams, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant98(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant101(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant100< + fn __pop_Variant103< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::UnaryOp, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant100(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant103(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -19076,13 +19113,13 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant71< + fn __pop_Variant74< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant71(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant74(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -19096,13 +19133,13 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant101< + fn __pop_Variant104< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option<(String, bool)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant101(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant104(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -19136,20 +19173,20 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant93< + fn __pop_Variant96< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option>, TextSize) + ) -> (TextSize, core::option::Option>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant93(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant96(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } fn __pop_Variant62< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize) + ) -> (TextSize, core::option::Option>, crate::parser::ParenthesizedExpr)>>, TextSize) { match __symbols.pop() { Some((__l, __Symbol::Variant62(__v), __r)) => (__l, __v, __r), @@ -19166,23 +19203,23 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant34< + fn __pop_Variant41< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option>, TextSize) + ) -> (TextSize, core::option::Option>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant34(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant41(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant41< + fn __pop_Variant34< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option>, TextSize) + ) -> (TextSize, core::option::Option>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant41(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant34(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -19206,6 +19243,16 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } + fn __pop_Variant71< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, core::option::Option, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant71(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant24< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -19236,43 +19283,43 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant16< + fn __pop_Variant91< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option, TextSize) + ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant16(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant91(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant88< + fn __pop_Variant26< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option, TextSize) + ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant88(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant26(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant26< + fn __pop_Variant102< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option, TextSize) + ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant26(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant102(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant99< + fn __pop_Variant16< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option, TextSize) + ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant99(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant16(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -19286,6 +19333,16 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } + fn __pop_Variant15< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, crate::parser::ParenthesizedExpr, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant15(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant2< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -19306,13 +19363,13 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant74< + fn __pop_Variant77< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, u32, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant74(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant77(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -19325,11 +19382,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ","? = "," => ActionFn(381); + // ","? = "," => ActionFn(384); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action381::<>(source_code, mode, __sym0); + let __nt = super::__action384::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (1, 0) } @@ -19342,10 +19399,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ","? = => ActionFn(382); + // ","? = => ActionFn(385); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action382::<>(source_code, mode, &__start, &__end); + let __nt = super::__action385::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (0, 0) } @@ -19358,11 +19415,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ";"? = ";" => ActionFn(405); + // ";"? = ";" => ActionFn(408); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action405::<>(source_code, mode, __sym0); + let __nt = super::__action408::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (1, 1) } @@ -19375,10 +19432,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ";"? = => ActionFn(406); + // ";"? = => ActionFn(409); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action406::<>(source_code, mode, &__start, &__end); + let __nt = super::__action409::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (0, 1) } @@ -19391,11 +19448,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // "="? = "=" => ActionFn(268); + // "="? = "=" => ActionFn(271); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action268::<>(source_code, mode, __sym0); + let __nt = super::__action271::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (1, 2) } @@ -19408,10 +19465,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // "="? = => ActionFn(269); + // "="? = => ActionFn(272); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action269::<>(source_code, mode, &__start, &__end); + let __nt = super::__action272::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (0, 2) } @@ -19424,11 +19481,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // "async"? = "async" => ActionFn(332); + // "async"? = "async" => ActionFn(337); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action332::<>(source_code, mode, __sym0); + let __nt = super::__action337::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (1, 3) } @@ -19441,10 +19498,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // "async"? = => ActionFn(333); + // "async"? = => ActionFn(338); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action333::<>(source_code, mode, &__start, &__end); + let __nt = super::__action338::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (0, 3) } @@ -19457,13 +19514,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", KwargParameter => ActionFn(437); + // ("," >) = ",", KwargParameter => ActionFn(440); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant9(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action437::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action440::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); (2, 4) } @@ -19476,13 +19533,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = ",", KwargParameter => ActionFn(686); + // ("," >)? = ",", KwargParameter => ActionFn(689); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant9(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action686::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action689::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (2, 5) } @@ -19495,10 +19552,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(490); + // ("," >)? = => ActionFn(493); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action490::<>(source_code, mode, &__start, &__end); + let __nt = super::__action493::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (0, 5) } @@ -19511,13 +19568,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", KwargParameter => ActionFn(445); + // ("," >) = ",", KwargParameter => ActionFn(448); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant9(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action445::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action448::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); (2, 6) } @@ -19530,13 +19587,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = ",", KwargParameter => ActionFn(691); + // ("," >)? = ",", KwargParameter => ActionFn(694); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant9(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action691::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action694::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (2, 7) } @@ -19549,10 +19606,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(479); + // ("," >)? = => ActionFn(482); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action479::<>(source_code, mode, &__start, &__end); + let __nt = super::__action482::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (0, 7) } @@ -19565,13 +19622,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", ParameterDef => ActionFn(493); + // ("," >) = ",", ParameterDef => ActionFn(496); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action493::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action496::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); (2, 8) } @@ -19584,10 +19641,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = => ActionFn(491); + // ("," >)* = => ActionFn(494); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action491::<>(source_code, mode, &__start, &__end); + let __nt = super::__action494::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); (0, 9) } @@ -19600,11 +19657,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = ("," >)+ => ActionFn(492); + // ("," >)* = ("," >)+ => ActionFn(495); let __sym0 = __pop_Variant12(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action492::<>(source_code, mode, __sym0); + let __nt = super::__action495::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); (1, 9) } @@ -19617,13 +19674,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ",", ParameterDef => ActionFn(696); + // ("," >)+ = ",", ParameterDef => ActionFn(699); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action696::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action699::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); (2, 10) } @@ -19636,14 +19693,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ("," >)+, ",", ParameterDef => ActionFn(697); + // ("," >)+ = ("," >)+, ",", ParameterDef => ActionFn(700); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant11(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant12(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action697::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action700::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); (3, 10) } @@ -19656,13 +19713,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", ParameterDef => ActionFn(482); + // ("," >) = ",", ParameterDef => ActionFn(485); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action482::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action485::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); (2, 11) } @@ -19675,10 +19732,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = => ActionFn(480); + // ("," >)* = => ActionFn(483); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action480::<>(source_code, mode, &__start, &__end); + let __nt = super::__action483::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); (0, 12) } @@ -19691,11 +19748,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = ("," >)+ => ActionFn(481); + // ("," >)* = ("," >)+ => ActionFn(484); let __sym0 = __pop_Variant12(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action481::<>(source_code, mode, __sym0); + let __nt = super::__action484::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); (1, 12) } @@ -19708,13 +19765,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ",", ParameterDef => ActionFn(704); + // ("," >)+ = ",", ParameterDef => ActionFn(707); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action704::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action707::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); (2, 13) } @@ -19727,14 +19784,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ("," >)+, ",", ParameterDef => ActionFn(705); + // ("," >)+ = ("," >)+, ",", ParameterDef => ActionFn(708); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant11(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant12(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action705::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action708::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); (3, 13) } @@ -19747,10 +19804,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(440); + // ("," >)? = => ActionFn(443); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action440::<>(source_code, mode, &__start, &__end); + let __nt = super::__action443::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant14(__nt), __end)); (0, 15) } @@ -19763,10 +19820,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(448); + // ("," >)? = => ActionFn(451); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action448::<>(source_code, mode, &__start, &__end); + let __nt = super::__action451::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant14(__nt), __end)); (0, 17) } @@ -19779,13 +19836,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", Test<"all"> => ActionFn(375); + // ("," >) = ",", Test<"all"> => ActionFn(378); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action375::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action378::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 18) } @@ -19798,13 +19855,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = ",", Test<"all"> => ActionFn(1076); + // ("," >)? = ",", Test<"all"> => ActionFn(1079); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1076::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1079::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (2, 19) } @@ -19817,10 +19874,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(374); + // ("," >)? = => ActionFn(377); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action374::<>(source_code, mode, &__start, &__end); + let __nt = super::__action377::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (0, 19) } @@ -19833,13 +19890,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," ) = ",", TestOrStarNamedExpr => ActionFn(568); + // ("," ) = ",", TestOrStarNamedExpr => ActionFn(571); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action568::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action571::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 20) } @@ -19852,10 +19909,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," )* = => ActionFn(566); + // ("," )* = => ActionFn(569); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action566::<>(source_code, mode, &__start, &__end); + let __nt = super::__action569::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (0, 21) } @@ -19868,11 +19925,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," )* = ("," )+ => ActionFn(567); + // ("," )* = ("," )+ => ActionFn(570); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action567::<>(source_code, mode, __sym0); + let __nt = super::__action570::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (1, 21) } @@ -19885,13 +19942,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," )+ = ",", TestOrStarNamedExpr => ActionFn(1079); + // ("," )+ = ",", TestOrStarNamedExpr => ActionFn(1082); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1079::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1082::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (2, 22) } @@ -19904,14 +19961,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," )+ = ("," )+, ",", TestOrStarNamedExpr => ActionFn(1080); + // ("," )+ = ("," )+, ",", TestOrStarNamedExpr => ActionFn(1083); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1080::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1083::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (3, 22) } @@ -19924,13 +19981,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", WithItem<"all"> => ActionFn(316); + // ("," >) = ",", WithItem<"all"> => ActionFn(321); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action316::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action321::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant18(__nt), __end)); (2, 23) } @@ -19943,10 +20000,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = => ActionFn(314); + // ("," >)* = => ActionFn(319); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action314::<>(source_code, mode, &__start, &__end); + let __nt = super::__action319::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant19(__nt), __end)); (0, 24) } @@ -19959,11 +20016,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = ("," >)+ => ActionFn(315); + // ("," >)* = ("," >)+ => ActionFn(320); let __sym0 = __pop_Variant19(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action315::<>(source_code, mode, __sym0); + let __nt = super::__action320::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant19(__nt), __end)); (1, 24) } @@ -19976,13 +20033,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ",", WithItem<"all"> => ActionFn(1089); + // ("," >)+ = ",", WithItem<"all"> => ActionFn(1092); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1089::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1092::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant19(__nt), __end)); (2, 25) } @@ -19995,14 +20052,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ("," >)+, ",", WithItem<"all"> => ActionFn(1090); + // ("," >)+ = ("," >)+, ",", WithItem<"all"> => ActionFn(1093); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant18(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant19(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1090::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1093::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant19(__nt), __end)); (3, 25) } @@ -20015,13 +20072,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("->" >) = "->", Test<"all"> => ActionFn(303); + // ("->" >) = "->", Test<"all"> => ActionFn(308); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action303::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action308::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 26) } @@ -20034,13 +20091,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("->" >)? = "->", Test<"all"> => ActionFn(1095); + // ("->" >)? = "->", Test<"all"> => ActionFn(1098); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1095::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1098::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (2, 27) } @@ -20053,10 +20110,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("->" >)? = => ActionFn(302); + // ("->" >)? = => ActionFn(307); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action302::<>(source_code, mode, &__start, &__end); + let __nt = super::__action307::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (0, 27) } @@ -20069,13 +20126,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("." Identifier) = ".", Identifier => ActionFn(380); + // ("." Identifier) = ".", Identifier => ActionFn(383); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action380::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action383::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant20(__nt), __end)); (2, 28) } @@ -20088,13 +20145,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("." Identifier)+ = ".", Identifier => ActionFn(1100); + // ("." Identifier)+ = ".", Identifier => ActionFn(1103); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1100::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1103::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant21(__nt), __end)); (2, 29) } @@ -20107,14 +20164,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("." Identifier)+ = ("." Identifier)+, ".", Identifier => ActionFn(1101); + // ("." Identifier)+ = ("." Identifier)+, ".", Identifier => ActionFn(1104); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant21(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1101::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1104::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant21(__nt), __end)); (3, 29) } @@ -20127,13 +20184,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" >) = ":", Test<"all"> => ActionFn(293); + // (":" >) = ":", Test<"all"> => ActionFn(298); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action293::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action298::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 30) } @@ -20146,13 +20203,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" >)? = ":", Test<"all"> => ActionFn(1102); + // (":" >)? = ":", Test<"all"> => ActionFn(1105); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1102::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1105::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (2, 31) } @@ -20165,10 +20222,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" >)? = => ActionFn(292); + // (":" >)? = => ActionFn(297); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action292::<>(source_code, mode, &__start, &__end); + let __nt = super::__action297::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (0, 31) } @@ -20181,13 +20238,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" ) = ":", TestOrStarExpr => ActionFn(290); + // (":" ) = ":", TestOrStarExpr => ActionFn(295); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action290::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action295::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 32) } @@ -20200,13 +20257,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" )? = ":", TestOrStarExpr => ActionFn(1109); + // (":" )? = ":", TestOrStarExpr => ActionFn(1112); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1109::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1112::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (2, 33) } @@ -20219,10 +20276,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" )? = => ActionFn(289); + // (":" )? = => ActionFn(294); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action289::<>(source_code, mode, &__start, &__end); + let __nt = super::__action294::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (0, 33) } @@ -20235,11 +20292,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("?") = "?" => ActionFn(370); + // ("?") = "?" => ActionFn(373); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action370::<>(source_code, mode, __sym0); + let __nt = super::__action373::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant0(__nt), __end)); (1, 34) } @@ -20252,11 +20309,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("?")+ = "?" => ActionFn(1112); + // ("?")+ = "?" => ActionFn(1115); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1112::<>(source_code, mode, __sym0); + let __nt = super::__action1115::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant22(__nt), __end)); (1, 35) } @@ -20269,13 +20326,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("?")+ = ("?")+, "?" => ActionFn(1113); + // ("?")+ = ("?")+, "?" => ActionFn(1116); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant22(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1113::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1116::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant22(__nt), __end)); (2, 35) } @@ -20288,11 +20345,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n") = "\n" => ActionFn(412); + // ("\n") = "\n" => ActionFn(415); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action412::<>(source_code, mode, __sym0); + let __nt = super::__action415::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant0(__nt), __end)); (1, 36) } @@ -20305,10 +20362,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n")* = => ActionFn(410); + // ("\n")* = => ActionFn(413); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action410::<>(source_code, mode, &__start, &__end); + let __nt = super::__action413::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant22(__nt), __end)); (0, 37) } @@ -20321,11 +20378,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n")* = ("\n")+ => ActionFn(411); + // ("\n")* = ("\n")+ => ActionFn(414); let __sym0 = __pop_Variant22(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action411::<>(source_code, mode, __sym0); + let __nt = super::__action414::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant22(__nt), __end)); (1, 37) } @@ -20338,11 +20395,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n")+ = "\n" => ActionFn(1114); + // ("\n")+ = "\n" => ActionFn(1117); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1114::<>(source_code, mode, __sym0); + let __nt = super::__action1117::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant22(__nt), __end)); (1, 38) } @@ -20355,13 +20412,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n")+ = ("\n")+, "\n" => ActionFn(1115); + // ("\n")+ = ("\n")+, "\n" => ActionFn(1118); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant22(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1115::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1118::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant22(__nt), __end)); (2, 38) } @@ -20374,13 +20431,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("as" ) = "as", Identifier => ActionFn(423); + // ("as" ) = "as", Identifier => ActionFn(426); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action423::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action426::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant23(__nt), __end)); (2, 39) } @@ -20393,13 +20450,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("as" )? = "as", Identifier => ActionFn(1118); + // ("as" )? = "as", Identifier => ActionFn(1121); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1118::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1121::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant24(__nt), __end)); (2, 40) } @@ -20412,10 +20469,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("as" )? = => ActionFn(422); + // ("as" )? = => ActionFn(425); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action422::<>(source_code, mode, &__start, &__end); + let __nt = super::__action425::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant24(__nt), __end)); (0, 40) } @@ -20428,14 +20485,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("else" ":" ) = "else", ":", Suite => ActionFn(336); + // ("else" ":" ) = "else", ":", Suite => ActionFn(341); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action336::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action341::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (3, 41) } @@ -20448,14 +20505,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("else" ":" )? = "else", ":", Suite => ActionFn(1123); + // ("else" ":" )? = "else", ":", Suite => ActionFn(1126); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1123::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1126::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant26(__nt), __end)); (3, 42) } @@ -20468,10 +20525,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("else" ":" )? = => ActionFn(335); + // ("else" ":" )? = => ActionFn(340); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action335::<>(source_code, mode, &__start, &__end); + let __nt = super::__action340::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant26(__nt), __end)); (0, 42) } @@ -20484,14 +20541,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("finally" ":" ) = "finally", ":", Suite => ActionFn(329); + // ("finally" ":" ) = "finally", ":", Suite => ActionFn(334); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action329::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action334::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (3, 43) } @@ -20504,14 +20561,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("finally" ":" )? = "finally", ":", Suite => ActionFn(1134); + // ("finally" ":" )? = "finally", ":", Suite => ActionFn(1137); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1134::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1137::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant26(__nt), __end)); (3, 44) } @@ -20524,10 +20581,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("finally" ":" )? = => ActionFn(328); + // ("finally" ":" )? = => ActionFn(333); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action328::<>(source_code, mode, &__start, &__end); + let __nt = super::__action333::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant26(__nt), __end)); (0, 44) } @@ -20540,13 +20597,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("from" >) = "from", Test<"all"> => ActionFn(395); + // ("from" >) = "from", Test<"all"> => ActionFn(398); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action395::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action398::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 45) } @@ -20559,13 +20616,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("from" >)? = "from", Test<"all"> => ActionFn(1144); + // ("from" >)? = "from", Test<"all"> => ActionFn(1147); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1144::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1147::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (2, 46) } @@ -20578,10 +20635,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("from" >)? = => ActionFn(394); + // ("from" >)? = => ActionFn(397); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action394::<>(source_code, mode, &__start, &__end); + let __nt = super::__action397::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (0, 46) } @@ -20594,7 +20651,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" ) = "elif", NamedExpressionTest, ":", Suite => ActionFn(720); + // (<@L> "elif" ":" ) = "elif", NamedExpressionTest, ":", Suite => ActionFn(723); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -20602,7 +20659,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action720::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action723::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant27(__nt), __end)); (4, 47) } @@ -20615,10 +20672,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" )* = => ActionFn(340); + // (<@L> "elif" ":" )* = => ActionFn(345); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action340::<>(source_code, mode, &__start, &__end); + let __nt = super::__action345::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant28(__nt), __end)); (0, 48) } @@ -20631,11 +20688,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" )* = (<@L> "elif" ":" )+ => ActionFn(341); + // (<@L> "elif" ":" )* = (<@L> "elif" ":" )+ => ActionFn(346); let __sym0 = __pop_Variant28(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action341::<>(source_code, mode, __sym0); + let __nt = super::__action346::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant28(__nt), __end)); (1, 48) } @@ -20648,7 +20705,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" )+ = "elif", NamedExpressionTest, ":", Suite => ActionFn(1147); + // (<@L> "elif" ":" )+ = "elif", NamedExpressionTest, ":", Suite => ActionFn(1150); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -20656,7 +20713,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1147::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1150::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant28(__nt), __end)); (4, 49) } @@ -20669,7 +20726,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" )+ = (<@L> "elif" ":" )+, "elif", NamedExpressionTest, ":", Suite => ActionFn(1148); + // (<@L> "elif" ":" )+ = (<@L> "elif" ":" )+, "elif", NamedExpressionTest, ":", Suite => ActionFn(1151); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -20678,7 +20735,7 @@ mod __parse__Top { let __sym0 = __pop_Variant28(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1148::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1151::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant28(__nt), __end)); (5, 49) } @@ -20691,14 +20748,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "else" ":" ) = "else", ":", Suite => ActionFn(721); + // (<@L> "else" ":" ) = "else", ":", Suite => ActionFn(724); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action721::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action724::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant29(__nt), __end)); (3, 50) } @@ -20711,14 +20768,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "else" ":" )? = "else", ":", Suite => ActionFn(1151); + // (<@L> "else" ":" )? = "else", ":", Suite => ActionFn(1154); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1151::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1154::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant30(__nt), __end)); (3, 51) } @@ -20731,10 +20788,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "else" ":" )? = => ActionFn(338); + // (<@L> "else" ":" )? = => ActionFn(343); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action338::<>(source_code, mode, &__start, &__end); + let __nt = super::__action343::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant30(__nt), __end)); (0, 51) } @@ -20747,13 +20804,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "or") = AndTest<"all">, "or" => ActionFn(459); + // (> "or") = AndTest<"all">, "or" => ActionFn(462); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action459::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action462::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 52) } @@ -20766,13 +20823,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "or")+ = AndTest<"all">, "or" => ActionFn(1156); + // (> "or")+ = AndTest<"all">, "or" => ActionFn(1159); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1156::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1159::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (2, 53) } @@ -20785,14 +20842,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "or")+ = (> "or")+, AndTest<"all">, "or" => ActionFn(1157); + // (> "or")+ = (> "or")+, AndTest<"all">, "or" => ActionFn(1160); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1157::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1160::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (3, 53) } @@ -20805,13 +20862,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",") = FunctionArgument, "," => ActionFn(468); + // ( ",") = FunctionArgument, "," => ActionFn(471); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant31(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action468::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action471::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant31(__nt), __end)); (2, 54) } @@ -20824,10 +20881,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")* = => ActionFn(466); + // ( ",")* = => ActionFn(469); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action466::<>(source_code, mode, &__start, &__end); + let __nt = super::__action469::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant32(__nt), __end)); (0, 55) } @@ -20840,11 +20897,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")* = ( ",")+ => ActionFn(467); + // ( ",")* = ( ",")+ => ActionFn(470); let __sym0 = __pop_Variant32(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action467::<>(source_code, mode, __sym0); + let __nt = super::__action470::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant32(__nt), __end)); (1, 55) } @@ -20857,13 +20914,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")+ = FunctionArgument, "," => ActionFn(1158); + // ( ",")+ = FunctionArgument, "," => ActionFn(1161); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant31(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1158::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1161::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant32(__nt), __end)); (2, 56) } @@ -20876,14 +20933,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")+ = ( ",")+, FunctionArgument, "," => ActionFn(1159); + // ( ",")+ = ( ",")+, FunctionArgument, "," => ActionFn(1162); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant31(__symbols); let __sym0 = __pop_Variant32(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1159::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1162::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant32(__nt), __end)); (3, 56) } @@ -20896,13 +20953,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "and") = NotTest<"all">, "and" => ActionFn(473); + // (> "and") = NotTest<"all">, "and" => ActionFn(476); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action473::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action476::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 57) } @@ -20915,13 +20972,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "and")+ = NotTest<"all">, "and" => ActionFn(1162); + // (> "and")+ = NotTest<"all">, "and" => ActionFn(1165); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1162::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1165::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (2, 58) } @@ -20934,14 +20991,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "and")+ = (> "and")+, NotTest<"all">, "and" => ActionFn(1163); + // (> "and")+ = (> "and")+, NotTest<"all">, "and" => ActionFn(1166); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1163::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1166::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (3, 58) } @@ -20954,13 +21011,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (>> ",") = OneOrMore>, "," => ActionFn(571); + // (>> ",") = OneOrMore>, "," => ActionFn(574); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action571::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action574::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (2, 59) } @@ -20973,13 +21030,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (>> ",")? = OneOrMore>, "," => ActionFn(1164); + // (>> ",")? = OneOrMore>, "," => ActionFn(1167); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1164::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1167::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant34(__nt), __end)); (2, 60) } @@ -20992,10 +21049,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (>> ",")? = => ActionFn(570); + // (>> ",")? = => ActionFn(573); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action570::<>(source_code, mode, &__start, &__end); + let __nt = super::__action573::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant34(__nt), __end)); (0, 60) } @@ -21008,13 +21065,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",") = Pattern, "," => ActionFn(356); + // ( ",") = Pattern, "," => ActionFn(359); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action356::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action359::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 61) } @@ -21027,10 +21084,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")* = => ActionFn(428); + // ( ",")* = => ActionFn(431); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action428::<>(source_code, mode, &__start, &__end); + let __nt = super::__action431::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant36(__nt), __end)); (0, 62) } @@ -21043,11 +21100,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")* = ( ",")+ => ActionFn(429); + // ( ",")* = ( ",")+ => ActionFn(432); let __sym0 = __pop_Variant36(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action429::<>(source_code, mode, __sym0); + let __nt = super::__action432::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant36(__nt), __end)); (1, 62) } @@ -21060,13 +21117,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")+ = Pattern, "," => ActionFn(1181); + // ( ",")+ = Pattern, "," => ActionFn(1184); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1181::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1184::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant36(__nt), __end)); (2, 63) } @@ -21079,14 +21136,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")+ = ( ",")+, Pattern, "," => ActionFn(1182); + // ( ",")+ = ( ",")+, Pattern, "," => ActionFn(1185); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant36(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1182::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1185::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant36(__nt), __end)); (3, 63) } @@ -21099,13 +21156,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";") = SmallStatement, ";" => ActionFn(409); + // ( ";") = SmallStatement, ";" => ActionFn(412); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action409::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action412::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (2, 64) } @@ -21118,10 +21175,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";")* = => ActionFn(407); + // ( ";")* = => ActionFn(410); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action407::<>(source_code, mode, &__start, &__end); + let __nt = super::__action410::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant38(__nt), __end)); (0, 65) } @@ -21134,11 +21191,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";")* = ( ";")+ => ActionFn(408); + // ( ";")* = ( ";")+ => ActionFn(411); let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action408::<>(source_code, mode, __sym0); + let __nt = super::__action411::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant38(__nt), __end)); (1, 65) } @@ -21151,13 +21208,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";")+ = SmallStatement, ";" => ActionFn(1185); + // ( ";")+ = SmallStatement, ";" => ActionFn(1188); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1185::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1188::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant38(__nt), __end)); (2, 66) } @@ -21170,14 +21227,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";")+ = ( ";")+, SmallStatement, ";" => ActionFn(1186); + // ( ";")+ = ( ";")+, SmallStatement, ";" => ActionFn(1189); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant37(__symbols); let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1186::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1189::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant38(__nt), __end)); (3, 66) } @@ -21190,14 +21247,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "as" ) = Test<"all">, "as", Identifier => ActionFn(324); + // (> "as" ) = Test<"all">, "as", Identifier => ActionFn(329); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action324::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action329::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant39(__nt), __end)); (3, 67) } @@ -21210,13 +21267,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",") = OneOrMore>, "," => ActionFn(1205); + // ( ",") = OneOrMore>, "," => ActionFn(1208); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1205::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1208::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); (2, 68) } @@ -21229,13 +21286,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")? = OneOrMore>, "," => ActionFn(1208); + // ( ",")? = OneOrMore>, "," => ActionFn(1211); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1208::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1211::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant41(__nt), __end)); (2, 69) } @@ -21248,10 +21305,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")? = => ActionFn(320); + // ( ",")? = => ActionFn(325); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action320::<>(source_code, mode, &__start, &__end); + let __nt = super::__action325::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant41(__nt), __end)); (0, 69) } @@ -21264,13 +21321,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (CompOp Expression<"all">) = CompOp, Expression<"all"> => ActionFn(516); + // (CompOp Expression<"all">) = CompOp, Expression<"all"> => ActionFn(519); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant56(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action516::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action519::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant42(__nt), __end)); (2, 70) } @@ -21283,13 +21340,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (CompOp Expression<"all">)+ = CompOp, Expression<"all"> => ActionFn(1217); + // (CompOp Expression<"all">)+ = CompOp, Expression<"all"> => ActionFn(1220); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant56(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1217::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1220::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant43(__nt), __end)); (2, 71) } @@ -21302,14 +21359,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (CompOp Expression<"all">)+ = (CompOp Expression<"all">)+, CompOp, Expression<"all"> => ActionFn(1218); + // (CompOp Expression<"all">)+ = (CompOp Expression<"all">)+, CompOp, Expression<"all"> => ActionFn(1221); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant56(__symbols); let __sym0 = __pop_Variant43(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1218::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1221::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant43(__nt), __end)); (3, 71) } @@ -21322,11 +21379,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (Guard) = Guard => ActionFn(363); + // (Guard) = Guard => ActionFn(366); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action363::<>(source_code, mode, __sym0); + let __nt = super::__action366::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); (1, 72) } @@ -21339,11 +21396,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (Guard)? = Guard => ActionFn(1219); + // (Guard)? = Guard => ActionFn(1222); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1219::<>(source_code, mode, __sym0); + let __nt = super::__action1222::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant45(__nt), __end)); (1, 73) } @@ -21356,10 +21413,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (Guard)? = => ActionFn(362); + // (Guard)? = => ActionFn(365); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action362::<>(source_code, mode, &__start, &__end); + let __nt = super::__action365::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant45(__nt), __end)); (0, 73) } @@ -21372,11 +21429,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (ParameterList) = ParameterList => ActionFn(296); + // (ParameterList) = ParameterList => ActionFn(301); let __sym0 = __pop_Variant46(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action296::<>(source_code, mode, __sym0); + let __nt = super::__action301::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (1, 74) } @@ -21389,11 +21446,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (ParameterList)? = ParameterList => ActionFn(1222); + // (ParameterList)? = ParameterList => ActionFn(1225); let __sym0 = __pop_Variant46(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1222::<>(source_code, mode, __sym0); + let __nt = super::__action1225::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant47(__nt), __end)); (1, 75) } @@ -21406,10 +21463,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (ParameterList)? = => ActionFn(295); + // (ParameterList)? = => ActionFn(300); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action295::<>(source_code, mode, &__start, &__end); + let __nt = super::__action300::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant47(__nt), __end)); (0, 75) } @@ -21422,10 +21479,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // @L = => ActionFn(414); + // @L = => ActionFn(417); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action414::<>(source_code, mode, &__start, &__end); + let __nt = super::__action417::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant48(__nt), __end)); (0, 76) } @@ -21438,10 +21495,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // @R = => ActionFn(413); + // @R = => ActionFn(416); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action413::<>(source_code, mode, &__start, &__end); + let __nt = super::__action416::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant48(__nt), __end)); (0, 77) } @@ -21454,11 +21511,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AddOp = "+" => ActionFn(196); + // AddOp = "+" => ActionFn(197); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action196::<>(source_code, mode, __sym0); + let __nt = super::__action197::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 78) } @@ -21471,11 +21528,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AddOp = "-" => ActionFn(197); + // AddOp = "-" => ActionFn(198); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action197::<>(source_code, mode, __sym0); + let __nt = super::__action198::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 78) } @@ -21488,14 +21545,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AddOpExpr = NumberExpr, AddOp, NumberAtom => ActionFn(1225); + // AddOpExpr = NumberExpr, AddOp, NumberAtom => ActionFn(1228); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant49(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1225::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1228::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 79) } @@ -21508,14 +21565,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndExpression<"all"> = AndExpression<"all">, "&", ShiftExpression<"all"> => ActionFn(1226); + // AndExpression<"all"> = AndExpression<"all">, "&", ShiftExpression<"all"> => ActionFn(1229); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1226::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1229::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 80) } @@ -21528,11 +21585,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndExpression<"all"> = ShiftExpression<"all"> => ActionFn(503); + // AndExpression<"all"> = ShiftExpression<"all"> => ActionFn(506); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action503::<>(source_code, mode, __sym0); + let __nt = super::__action506::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 80) } @@ -21545,14 +21602,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndExpression<"no-withitems"> = AndExpression<"all">, "&", ShiftExpression<"all"> => ActionFn(1227); + // AndExpression<"no-withitems"> = AndExpression<"all">, "&", ShiftExpression<"all"> => ActionFn(1230); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1227::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1230::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 81) } @@ -21565,11 +21622,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndExpression<"no-withitems"> = ShiftExpression<"no-withitems"> => ActionFn(534); + // AndExpression<"no-withitems"> = ShiftExpression<"no-withitems"> => ActionFn(537); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action534::<>(source_code, mode, __sym0); + let __nt = super::__action537::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 81) } @@ -21582,13 +21639,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndTest<"all"> = (> "and")+, NotTest<"all"> => ActionFn(1228); + // AndTest<"all"> = (> "and")+, NotTest<"all"> => ActionFn(1231); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1228::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1231::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 82) } @@ -21601,11 +21658,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndTest<"all"> = NotTest<"all"> => ActionFn(461); + // AndTest<"all"> = NotTest<"all"> => ActionFn(464); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action461::<>(source_code, mode, __sym0); + let __nt = super::__action464::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 82) } @@ -21618,13 +21675,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndTest<"no-withitems"> = (> "and")+, NotTest<"all"> => ActionFn(1229); + // AndTest<"no-withitems"> = (> "and")+, NotTest<"all"> => ActionFn(1232); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1229::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1232::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 83) } @@ -21637,11 +21694,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndTest<"no-withitems"> = NotTest<"no-withitems"> => ActionFn(507); + // AndTest<"no-withitems"> = NotTest<"no-withitems"> => ActionFn(510); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action507::<>(source_code, mode, __sym0); + let __nt = super::__action510::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 83) } @@ -21654,11 +21711,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Arguments? = Arguments => ActionFn(286); + // Arguments? = Arguments => ActionFn(291); let __sym0 = __pop_Variant50(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action286::<>(source_code, mode, __sym0); + let __nt = super::__action291::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant51(__nt), __end)); (1, 85) } @@ -21671,10 +21728,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Arguments? = => ActionFn(287); + // Arguments? = => ActionFn(292); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action287::<>(source_code, mode, &__start, &__end); + let __nt = super::__action292::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant51(__nt), __end)); (0, 85) } @@ -21687,14 +21744,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ArithmeticExpression<"all"> = ArithmeticExpression<"all">, AddOp, Term<"all"> => ActionFn(1231); + // ArithmeticExpression<"all"> = ArithmeticExpression<"all">, AddOp, Term<"all"> => ActionFn(1234); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant49(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1231::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1234::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 86) } @@ -21707,11 +21764,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ArithmeticExpression<"all"> = Term<"all"> => ActionFn(520); + // ArithmeticExpression<"all"> = Term<"all"> => ActionFn(523); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action520::<>(source_code, mode, __sym0); + let __nt = super::__action523::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 86) } @@ -21724,14 +21781,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ArithmeticExpression<"no-withitems"> = ArithmeticExpression<"all">, AddOp, Term<"all"> => ActionFn(1232); + // ArithmeticExpression<"no-withitems"> = ArithmeticExpression<"all">, AddOp, Term<"all"> => ActionFn(1235); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant49(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1232::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1235::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 87) } @@ -21744,11 +21801,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ArithmeticExpression<"no-withitems"> = Term<"no-withitems"> => ActionFn(544); + // ArithmeticExpression<"no-withitems"> = Term<"no-withitems"> => ActionFn(547); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action544::<>(source_code, mode, __sym0); + let __nt = super::__action547::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 87) } @@ -21761,7 +21818,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssertStatement = "assert", Test<"all">, ",", Test<"all"> => ActionFn(1234); + // AssertStatement = "assert", Test<"all">, ",", Test<"all"> => ActionFn(1237); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -21769,7 +21826,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1234::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1237::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (4, 89) } @@ -21782,13 +21839,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssertStatement = "assert", Test<"all"> => ActionFn(1235); + // AssertStatement = "assert", Test<"all"> => ActionFn(1238); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1235::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1238::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (2, 89) } @@ -21839,10 +21896,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix* = => ActionFn(403); + // AssignSuffix* = => ActionFn(406); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action403::<>(source_code, mode, &__start, &__end); + let __nt = super::__action406::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (0, 91) } @@ -21855,11 +21912,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix* = AssignSuffix+ => ActionFn(404); + // AssignSuffix* = AssignSuffix+ => ActionFn(407); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action404::<>(source_code, mode, __sym0); + let __nt = super::__action407::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (1, 91) } @@ -21872,11 +21929,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix+ = AssignSuffix => ActionFn(419); + // AssignSuffix+ = AssignSuffix => ActionFn(422); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action419::<>(source_code, mode, __sym0); + let __nt = super::__action422::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (1, 92) } @@ -21889,13 +21946,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix+ = AssignSuffix+, AssignSuffix => ActionFn(420); + // AssignSuffix+ = AssignSuffix+, AssignSuffix => ActionFn(423); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action420::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action423::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (2, 92) } @@ -21908,11 +21965,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix? = AssignSuffix => ActionFn(398); + // AssignSuffix? = AssignSuffix => ActionFn(401); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action398::<>(source_code, mode, __sym0); + let __nt = super::__action401::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (1, 93) } @@ -21925,13 +21982,30 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix? = => ActionFn(399); + // AssignSuffix? = => ActionFn(402); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action399::<>(source_code, mode, &__start, &__end); + let __nt = super::__action402::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); (0, 93) } + pub(crate) fn __reduce182< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // Atom<"all"> = String => ActionFn(548); + let __sym0 = __pop_Variant44(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action548::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 94) + } pub(crate) fn __reduce183< >( source_code: &str, @@ -21941,11 +22015,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = Number => ActionFn(1237); - let __sym0 = __pop_Variant81(__symbols); + // Atom<"all"> = Number => ActionFn(1239); + let __sym0 = __pop_Variant84(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1237::<>(source_code, mode, __sym0); + let __nt = super::__action1239::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 94) } @@ -21958,11 +22032,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = Identifier => ActionFn(1238); + // Atom<"all"> = Identifier => ActionFn(1240); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1238::<>(source_code, mode, __sym0); + let __nt = super::__action1240::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 94) } @@ -21975,14 +22049,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "[", ListLiteralValues, "]" => ActionFn(1599); + // Atom<"all"> = "[", ListLiteralValues, "]" => ActionFn(1603); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1599::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1603::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 94) } @@ -21995,13 +22069,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "[", "]" => ActionFn(1600); + // Atom<"all"> = "[", "]" => ActionFn(1604); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1600::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1604::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 94) } @@ -22014,7 +22088,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "[", TestOrStarNamedExpr, CompFor, "]" => ActionFn(1240); + // Atom<"all"> = "[", TestOrStarNamedExpr, CompFor, "]" => ActionFn(1242); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant54(__symbols); @@ -22022,7 +22096,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1240::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1242::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 94) } @@ -22035,7 +22109,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", OneOrMore>, ",", ")" => ActionFn(1241); + // Atom<"all"> = "(", OneOrMore>, ",", ")" => ActionFn(1243); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -22043,7 +22117,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1241::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1243::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 94) } @@ -22056,14 +22130,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", OneOrMore>, ")" => ActionFn(1242); + // Atom<"all"> = "(", OneOrMore>, ")" => ActionFn(1244); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1242::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1244::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 94) } @@ -22076,13 +22150,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", ")" => ActionFn(1251); + // Atom<"all"> = "(", ")" => ActionFn(1253); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1251::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1253::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 94) } @@ -22095,14 +22169,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", YieldExpr, ")" => ActionFn(1252); + // Atom<"all"> = "(", YieldExpr, ")" => ActionFn(1254); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1252::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1254::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 94) } @@ -22115,7 +22189,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", NamedExpressionTest, CompFor, ")" => ActionFn(1253); + // Atom<"all"> = "(", NamedExpressionTest, CompFor, ")" => ActionFn(1255); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant54(__symbols); @@ -22123,7 +22197,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1253::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1255::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 94) } @@ -22136,14 +22210,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", DictLiteralValues, "}" => ActionFn(1567); + // Atom<"all"> = "{", DictLiteralValues, "}" => ActionFn(1571); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant61(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1567::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1571::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 94) } @@ -22156,13 +22230,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", "}" => ActionFn(1568); + // Atom<"all"> = "{", "}" => ActionFn(1572); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1568::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1572::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 94) } @@ -22175,7 +22249,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", DictEntry, CompFor, "}" => ActionFn(1256); + // Atom<"all"> = "{", DictEntry, CompFor, "}" => ActionFn(1258); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant54(__symbols); @@ -22183,7 +22257,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1256::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1258::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 94) } @@ -22196,14 +22270,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", SetLiteralValues, "}" => ActionFn(1257); + // Atom<"all"> = "{", SetLiteralValues, "}" => ActionFn(1259); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1257::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1259::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 94) } @@ -22216,7 +22290,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", NamedExpressionTest, CompFor, "}" => ActionFn(1258); + // Atom<"all"> = "{", NamedExpressionTest, CompFor, "}" => ActionFn(1260); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant54(__symbols); @@ -22224,7 +22298,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1258::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1260::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 94) } @@ -22237,11 +22311,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "True" => ActionFn(1259); + // Atom<"all"> = "True" => ActionFn(1261); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1259::<>(source_code, mode, __sym0); + let __nt = super::__action1261::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 94) } @@ -22254,11 +22328,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "False" => ActionFn(1260); + // Atom<"all"> = "False" => ActionFn(1262); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1260::<>(source_code, mode, __sym0); + let __nt = super::__action1262::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 94) } @@ -22271,11 +22345,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "None" => ActionFn(1261); + // Atom<"all"> = "None" => ActionFn(1263); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1261::<>(source_code, mode, __sym0); + let __nt = super::__action1263::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 94) } @@ -22288,14 +22362,31 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "..." => ActionFn(1262); + // Atom<"all"> = "..." => ActionFn(1264); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1262::<>(source_code, mode, __sym0); + let __nt = super::__action1264::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 94) } + pub(crate) fn __reduce211< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // Atom<"no-withitems"> = String => ActionFn(591); + let __sym0 = __pop_Variant44(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action591::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 95) + } pub(crate) fn __reduce212< >( source_code: &str, @@ -22305,11 +22396,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = Number => ActionFn(1264); - let __sym0 = __pop_Variant81(__symbols); + // Atom<"no-withitems"> = Number => ActionFn(1265); + let __sym0 = __pop_Variant84(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1264::<>(source_code, mode, __sym0); + let __nt = super::__action1265::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 95) } @@ -22322,11 +22413,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = Identifier => ActionFn(1265); + // Atom<"no-withitems"> = Identifier => ActionFn(1266); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1265::<>(source_code, mode, __sym0); + let __nt = super::__action1266::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 95) } @@ -22339,14 +22430,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "[", ListLiteralValues, "]" => ActionFn(1601); + // Atom<"no-withitems"> = "[", ListLiteralValues, "]" => ActionFn(1605); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1601::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1605::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 95) } @@ -22359,13 +22450,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "[", "]" => ActionFn(1602); + // Atom<"no-withitems"> = "[", "]" => ActionFn(1606); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1602::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1606::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 95) } @@ -22378,7 +22469,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "[", TestOrStarNamedExpr, CompFor, "]" => ActionFn(1267); + // Atom<"no-withitems"> = "[", TestOrStarNamedExpr, CompFor, "]" => ActionFn(1268); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant54(__symbols); @@ -22386,7 +22477,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1267::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1268::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 95) } @@ -22399,13 +22490,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "(", ")" => ActionFn(1276); + // Atom<"no-withitems"> = "(", ")" => ActionFn(1277); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1276::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1277::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 95) } @@ -22418,14 +22509,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "(", YieldExpr, ")" => ActionFn(1277); + // Atom<"no-withitems"> = "(", YieldExpr, ")" => ActionFn(1278); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1277::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1278::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 95) } @@ -22438,7 +22529,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "(", NamedExpressionTest, CompFor, ")" => ActionFn(1278); + // Atom<"no-withitems"> = "(", NamedExpressionTest, CompFor, ")" => ActionFn(1279); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant54(__symbols); @@ -22446,7 +22537,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1278::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1279::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 95) } @@ -22459,14 +22550,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", DictLiteralValues, "}" => ActionFn(1569); + // Atom<"no-withitems"> = "{", DictLiteralValues, "}" => ActionFn(1573); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant61(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1569::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1573::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 95) } @@ -22479,13 +22570,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", "}" => ActionFn(1570); + // Atom<"no-withitems"> = "{", "}" => ActionFn(1574); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1570::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1574::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 95) } @@ -22498,7 +22589,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", DictEntry, CompFor, "}" => ActionFn(1281); + // Atom<"no-withitems"> = "{", DictEntry, CompFor, "}" => ActionFn(1282); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant54(__symbols); @@ -22506,7 +22597,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1281::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1282::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 95) } @@ -22519,14 +22610,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", SetLiteralValues, "}" => ActionFn(1282); + // Atom<"no-withitems"> = "{", SetLiteralValues, "}" => ActionFn(1283); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1282::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1283::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 95) } @@ -22539,7 +22630,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", NamedExpressionTest, CompFor, "}" => ActionFn(1283); + // Atom<"no-withitems"> = "{", NamedExpressionTest, CompFor, "}" => ActionFn(1284); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant54(__symbols); @@ -22547,7 +22638,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1283::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1284::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 95) } @@ -22560,11 +22651,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "True" => ActionFn(1284); + // Atom<"no-withitems"> = "True" => ActionFn(1285); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1284::<>(source_code, mode, __sym0); + let __nt = super::__action1285::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 95) } @@ -22577,11 +22668,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "False" => ActionFn(1285); + // Atom<"no-withitems"> = "False" => ActionFn(1286); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1285::<>(source_code, mode, __sym0); + let __nt = super::__action1286::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 95) } @@ -22594,11 +22685,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "None" => ActionFn(1286); + // Atom<"no-withitems"> = "None" => ActionFn(1287); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1286::<>(source_code, mode, __sym0); + let __nt = super::__action1287::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 95) } @@ -22611,11 +22702,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "..." => ActionFn(1287); + // Atom<"no-withitems"> = "..." => ActionFn(1288); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1287::<>(source_code, mode, __sym0); + let __nt = super::__action1288::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 95) } @@ -22628,11 +22719,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"all"> = Atom<"all"> => ActionFn(537); + // AtomExpr2<"all"> = Atom<"all"> => ActionFn(540); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action537::<>(source_code, mode, __sym0); + let __nt = super::__action540::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 96) } @@ -22645,13 +22736,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"all"> = AtomExpr2<"all">, Arguments => ActionFn(1288); + // AtomExpr2<"all"> = AtomExpr2<"all">, Arguments => ActionFn(1289); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant50(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1288::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1289::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 96) } @@ -22664,7 +22755,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"all"> = AtomExpr2<"all">, "[", SubscriptList, "]" => ActionFn(1289); + // AtomExpr2<"all"> = AtomExpr2<"all">, "[", SubscriptList, "]" => ActionFn(1290); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant15(__symbols); @@ -22672,7 +22763,7 @@ mod __parse__Top { let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1289::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1290::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 96) } @@ -22685,14 +22776,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"all"> = AtomExpr2<"all">, ".", Identifier => ActionFn(1290); + // AtomExpr2<"all"> = AtomExpr2<"all">, ".", Identifier => ActionFn(1291); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1290::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1291::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 96) } @@ -22705,11 +22796,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"no-withitems"> = Atom<"no-withitems"> => ActionFn(584); + // AtomExpr2<"no-withitems"> = Atom<"no-withitems"> => ActionFn(587); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action584::<>(source_code, mode, __sym0); + let __nt = super::__action587::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 97) } @@ -22722,13 +22813,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, Arguments => ActionFn(1291); + // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, Arguments => ActionFn(1292); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant50(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1291::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1292::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 97) } @@ -22741,7 +22832,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, "[", SubscriptList, "]" => ActionFn(1292); + // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, "[", SubscriptList, "]" => ActionFn(1293); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant15(__symbols); @@ -22749,7 +22840,7 @@ mod __parse__Top { let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1292::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1293::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (4, 97) } @@ -22762,14 +22853,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, ".", Identifier => ActionFn(1293); + // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, ".", Identifier => ActionFn(1294); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1293::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1294::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 97) } @@ -22782,13 +22873,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr<"all"> = "await", AtomExpr2<"all"> => ActionFn(1294); + // AtomExpr<"all"> = "await", AtomExpr2<"all"> => ActionFn(1295); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1294::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1295::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 98) } @@ -22801,11 +22892,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr<"all"> = AtomExpr2<"all"> => ActionFn(536); + // AtomExpr<"all"> = AtomExpr2<"all"> => ActionFn(539); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action536::<>(source_code, mode, __sym0); + let __nt = super::__action539::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 98) } @@ -22818,13 +22909,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr<"no-withitems"> = "await", AtomExpr2<"all"> => ActionFn(1295); + // AtomExpr<"no-withitems"> = "await", AtomExpr2<"all"> => ActionFn(1296); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1295::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1296::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 99) } @@ -22837,11 +22928,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr<"no-withitems"> = AtomExpr2<"no-withitems"> => ActionFn(583); + // AtomExpr<"no-withitems"> = AtomExpr2<"no-withitems"> => ActionFn(586); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action583::<>(source_code, mode, __sym0); + let __nt = super::__action586::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 99) } @@ -23075,11 +23166,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CapturePattern = Identifier => ActionFn(1296); + // CapturePattern = Identifier => ActionFn(1297); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1296::<>(source_code, mode, __sym0); + let __nt = super::__action1297::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 101) } @@ -23092,17 +23183,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = "class", Identifier, TypeParams, Arguments, ":", Suite => ActionFn(1755); + // ClassDef = "class", Identifier, TypeParams, Arguments, ":", Suite => ActionFn(1759); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant50(__symbols); - let __sym2 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant101(__symbols); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1755::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1759::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (6, 102) } @@ -23115,7 +23206,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = "class", Identifier, Arguments, ":", Suite => ActionFn(1756); + // ClassDef = "class", Identifier, Arguments, ":", Suite => ActionFn(1760); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -23124,7 +23215,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1756::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1760::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (5, 102) } @@ -23137,18 +23228,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = Decorator+, "class", Identifier, TypeParams, Arguments, ":", Suite => ActionFn(1757); + // ClassDef = Decorator+, "class", Identifier, TypeParams, Arguments, ":", Suite => ActionFn(1761); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant50(__symbols); - let __sym3 = __pop_Variant98(__symbols); + let __sym3 = __pop_Variant101(__symbols); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1757::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1761::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 102) } @@ -23161,7 +23252,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = Decorator+, "class", Identifier, Arguments, ":", Suite => ActionFn(1758); + // ClassDef = Decorator+, "class", Identifier, Arguments, ":", Suite => ActionFn(1762); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -23171,7 +23262,7 @@ mod __parse__Top { let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1758::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1762::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (6, 102) } @@ -23184,16 +23275,16 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = "class", Identifier, TypeParams, ":", Suite => ActionFn(1759); + // ClassDef = "class", Identifier, TypeParams, ":", Suite => ActionFn(1763); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant101(__symbols); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1759::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1763::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (5, 102) } @@ -23206,7 +23297,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = "class", Identifier, ":", Suite => ActionFn(1760); + // ClassDef = "class", Identifier, ":", Suite => ActionFn(1764); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -23214,7 +23305,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1760::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1764::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (4, 102) } @@ -23227,17 +23318,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = Decorator+, "class", Identifier, TypeParams, ":", Suite => ActionFn(1761); + // ClassDef = Decorator+, "class", Identifier, TypeParams, ":", Suite => ActionFn(1765); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant98(__symbols); + let __sym3 = __pop_Variant101(__symbols); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1761::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1765::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (6, 102) } @@ -23250,7 +23341,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = Decorator+, "class", Identifier, ":", Suite => ActionFn(1762); + // ClassDef = Decorator+, "class", Identifier, ":", Suite => ActionFn(1766); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -23259,7 +23350,7 @@ mod __parse__Top { let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1762::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1766::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (5, 102) } @@ -23272,13 +23363,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassPattern = MatchName, PatternArguments => ActionFn(1297); + // ClassPattern = MatchName, PatternArguments => ActionFn(1298); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant89(__symbols); + let __sym1 = __pop_Variant92(__symbols); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1297::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1298::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 103) } @@ -23291,13 +23382,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassPattern = MatchNameOrAttr, PatternArguments => ActionFn(1298); + // ClassPattern = MatchNameOrAttr, PatternArguments => ActionFn(1299); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant89(__symbols); + let __sym1 = __pop_Variant92(__symbols); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1298::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1299::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 103) } @@ -23429,11 +23520,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = FunctionArgument => ActionFn(1533); + // Comma = FunctionArgument => ActionFn(1537); let __sym0 = __pop_Variant31(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1533::<>(source_code, mode, __sym0); + let __nt = super::__action1537::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant52(__nt), __end)); (1, 105) } @@ -23446,10 +23537,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = => ActionFn(1534); + // Comma = => ActionFn(1538); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action1534::<>(source_code, mode, &__start, &__end); + let __nt = super::__action1538::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant52(__nt), __end)); (0, 105) } @@ -23462,13 +23553,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = ( ",")+, FunctionArgument => ActionFn(1535); + // Comma = ( ",")+, FunctionArgument => ActionFn(1539); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant31(__symbols); let __sym0 = __pop_Variant32(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1535::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1539::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant52(__nt), __end)); (2, 105) } @@ -23481,11 +23572,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = ( ",")+ => ActionFn(1536); + // Comma = ( ",")+ => ActionFn(1540); let __sym0 = __pop_Variant32(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1536::<>(source_code, mode, __sym0); + let __nt = super::__action1540::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant52(__nt), __end)); (1, 105) } @@ -23498,11 +23589,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = Pattern => ActionFn(1541); + // Comma = Pattern => ActionFn(1545); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1541::<>(source_code, mode, __sym0); + let __nt = super::__action1545::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); (1, 106) } @@ -23515,10 +23606,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = => ActionFn(1542); + // Comma = => ActionFn(1546); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action1542::<>(source_code, mode, &__start, &__end); + let __nt = super::__action1546::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); (0, 106) } @@ -23531,13 +23622,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = ( ",")+, Pattern => ActionFn(1543); + // Comma = ( ",")+, Pattern => ActionFn(1547); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant36(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1543::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1547::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); (2, 106) } @@ -23550,11 +23641,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = ( ",")+ => ActionFn(1544); + // Comma = ( ",")+ => ActionFn(1548); let __sym0 = __pop_Variant36(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1544::<>(source_code, mode, __sym0); + let __nt = super::__action1548::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); (1, 106) } @@ -23567,11 +23658,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompFor = SingleForComprehension+ => ActionFn(234); - let __sym0 = __pop_Variant91(__symbols); + // CompFor = SingleForComprehension+ => ActionFn(237); + let __sym0 = __pop_Variant94(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action234::<>(source_code, mode, __sym0); + let __nt = super::__action237::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant54(__nt), __end)); (1, 107) } @@ -23584,11 +23675,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompFor? = CompFor => ActionFn(247); + // CompFor? = CompFor => ActionFn(250); let __sym0 = __pop_Variant54(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action247::<>(source_code, mode, __sym0); + let __nt = super::__action250::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant55(__nt), __end)); (1, 108) } @@ -23601,10 +23692,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompFor? = => ActionFn(248); + // CompFor? = => ActionFn(251); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action248::<>(source_code, mode, &__start, &__end); + let __nt = super::__action251::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant55(__nt), __end)); (0, 108) } @@ -23617,11 +23708,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = "==" => ActionFn(184); + // CompOp = "==" => ActionFn(185); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action184::<>(source_code, mode, __sym0); + let __nt = super::__action185::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (1, 109) } @@ -23634,11 +23725,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = "!=" => ActionFn(185); + // CompOp = "!=" => ActionFn(186); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action185::<>(source_code, mode, __sym0); + let __nt = super::__action186::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (1, 109) } @@ -23651,11 +23742,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = "<" => ActionFn(186); + // CompOp = "<" => ActionFn(187); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action186::<>(source_code, mode, __sym0); + let __nt = super::__action187::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (1, 109) } @@ -23668,11 +23759,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = "<=" => ActionFn(187); + // CompOp = "<=" => ActionFn(188); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action187::<>(source_code, mode, __sym0); + let __nt = super::__action188::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (1, 109) } @@ -23685,11 +23776,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = ">" => ActionFn(188); + // CompOp = ">" => ActionFn(189); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action188::<>(source_code, mode, __sym0); + let __nt = super::__action189::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (1, 109) } @@ -23702,11 +23793,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = ">=" => ActionFn(189); + // CompOp = ">=" => ActionFn(190); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action189::<>(source_code, mode, __sym0); + let __nt = super::__action190::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (1, 109) } @@ -23719,11 +23810,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = "in" => ActionFn(190); + // CompOp = "in" => ActionFn(191); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action190::<>(source_code, mode, __sym0); + let __nt = super::__action191::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (1, 109) } @@ -23736,13 +23827,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = "not", "in" => ActionFn(191); + // CompOp = "not", "in" => ActionFn(192); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action191::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action192::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (2, 109) } @@ -23755,11 +23846,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = "is" => ActionFn(192); + // CompOp = "is" => ActionFn(193); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action192::<>(source_code, mode, __sym0); + let __nt = super::__action193::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (1, 109) } @@ -23772,13 +23863,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompOp = "is", "not" => ActionFn(193); + // CompOp = "is", "not" => ActionFn(194); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action193::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action194::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant56(__nt), __end)); (2, 109) } @@ -23791,13 +23882,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comparison<"all"> = Expression<"all">, (CompOp Expression<"all">)+ => ActionFn(1299); + // Comparison<"all"> = Expression<"all">, (CompOp Expression<"all">)+ => ActionFn(1300); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant43(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1299::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1300::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 110) } @@ -23810,11 +23901,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comparison<"all"> = Expression<"all"> => ActionFn(513); + // Comparison<"all"> = Expression<"all"> => ActionFn(516); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action513::<>(source_code, mode, __sym0); + let __nt = super::__action516::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 110) } @@ -23827,13 +23918,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comparison<"no-withitems"> = Expression<"all">, (CompOp Expression<"all">)+ => ActionFn(1300); + // Comparison<"no-withitems"> = Expression<"all">, (CompOp Expression<"all">)+ => ActionFn(1301); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant43(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1300::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1301::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 111) } @@ -23846,11 +23937,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comparison<"no-withitems"> = Expression<"no-withitems"> => ActionFn(524); + // Comparison<"no-withitems"> = Expression<"no-withitems"> => ActionFn(527); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action524::<>(source_code, mode, __sym0); + let __nt = super::__action527::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 111) } @@ -23999,13 +24090,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf = "if", ExpressionNoCond => ActionFn(237); + // ComprehensionIf = "if", ExpressionNoCond => ActionFn(240); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action237::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action240::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 113) } @@ -24018,10 +24109,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf* = => ActionFn(250); + // ComprehensionIf* = => ActionFn(253); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action250::<>(source_code, mode, &__start, &__end); + let __nt = super::__action253::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (0, 114) } @@ -24034,11 +24125,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf* = ComprehensionIf+ => ActionFn(251); + // ComprehensionIf* = ComprehensionIf+ => ActionFn(254); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action251::<>(source_code, mode, __sym0); + let __nt = super::__action254::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (1, 114) } @@ -24051,11 +24142,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf+ = ComprehensionIf => ActionFn(462); + // ComprehensionIf+ = ComprehensionIf => ActionFn(465); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action462::<>(source_code, mode, __sym0); + let __nt = super::__action465::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (1, 115) } @@ -24068,13 +24159,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf+ = ComprehensionIf+, ComprehensionIf => ActionFn(463); + // ComprehensionIf+ = ComprehensionIf+, ComprehensionIf => ActionFn(466); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action463::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action466::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant17(__nt), __end)); (2, 115) } @@ -24087,14 +24178,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator = "@", NamedExpressionTest, "\n" => ActionFn(1301); + // Decorator = "@", NamedExpressionTest, "\n" => ActionFn(1302); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1301::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1302::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant57(__nt), __end)); (3, 116) } @@ -24107,10 +24198,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator* = => ActionFn(306); + // Decorator* = => ActionFn(311); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action306::<>(source_code, mode, &__start, &__end); + let __nt = super::__action311::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant58(__nt), __end)); (0, 117) } @@ -24123,11 +24214,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator* = Decorator+ => ActionFn(307); + // Decorator* = Decorator+ => ActionFn(312); let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action307::<>(source_code, mode, __sym0); + let __nt = super::__action312::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant58(__nt), __end)); (1, 117) } @@ -24140,11 +24231,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator+ = Decorator => ActionFn(435); + // Decorator+ = Decorator => ActionFn(438); let __sym0 = __pop_Variant57(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action435::<>(source_code, mode, __sym0); + let __nt = super::__action438::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant58(__nt), __end)); (1, 118) } @@ -24157,13 +24248,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator+ = Decorator+, Decorator => ActionFn(436); + // Decorator+ = Decorator+, Decorator => ActionFn(439); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant57(__symbols); let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action436::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action439::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant58(__nt), __end)); (2, 118) } @@ -24176,13 +24267,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DelStatement = "del", ExpressionList2 => ActionFn(1302); + // DelStatement = "del", ExpressionList2 => ActionFn(1303); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1302::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1303::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (2, 119) } @@ -24195,11 +24286,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictElement = DictEntry => ActionFn(225); + // DictElement = DictEntry => ActionFn(228); let __sym0 = __pop_Variant60(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action225::<>(source_code, mode, __sym0); + let __nt = super::__action228::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant59(__nt), __end)); (1, 120) } @@ -24212,13 +24303,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictElement = "**", Expression<"all"> => ActionFn(226); + // DictElement = "**", Expression<"all"> => ActionFn(229); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action226::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action229::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant59(__nt), __end)); (2, 120) } @@ -24231,14 +24322,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictEntry = Test<"all">, ":", Test<"all"> => ActionFn(224); + // DictEntry = Test<"all">, ":", Test<"all"> => ActionFn(227); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action224::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action227::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant60(__nt), __end)); (3, 121) } @@ -24251,13 +24342,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictLiteralValues = OneOrMore, "," => ActionFn(612); + // DictLiteralValues = OneOrMore, "," => ActionFn(615); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant61(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action612::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action615::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant61(__nt), __end)); (2, 122) } @@ -24270,11 +24361,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictLiteralValues = OneOrMore => ActionFn(613); + // DictLiteralValues = OneOrMore => ActionFn(616); let __sym0 = __pop_Variant61(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action613::<>(source_code, mode, __sym0); + let __nt = super::__action616::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant61(__nt), __end)); (1, 122) } @@ -24287,11 +24378,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictLiteralValues? = DictLiteralValues => ActionFn(564); + // DictLiteralValues? = DictLiteralValues => ActionFn(567); let __sym0 = __pop_Variant61(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action564::<>(source_code, mode, __sym0); + let __nt = super::__action567::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant62(__nt), __end)); (1, 123) } @@ -24304,10 +24395,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictLiteralValues? = => ActionFn(565); + // DictLiteralValues? = => ActionFn(568); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action565::<>(source_code, mode, &__start, &__end); + let __nt = super::__action568::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant62(__nt), __end)); (0, 123) } @@ -24320,11 +24411,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DottedName = name => ActionFn(1303); + // DottedName = name => ActionFn(1304); let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1303::<>(source_code, mode, __sym0); + let __nt = super::__action1304::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant23(__nt), __end)); (1, 124) } @@ -24337,13 +24428,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DottedName = name, ("." Identifier)+ => ActionFn(1304); + // DottedName = name, ("." Identifier)+ => ActionFn(1305); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant21(__symbols); let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1304::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1305::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant23(__nt), __end)); (2, 124) } @@ -24356,14 +24447,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DoubleStarTypedParameter = Identifier, ":", Test<"all"> => ActionFn(1305); + // DoubleStarTypedParameter = Identifier, ":", Test<"all"> => ActionFn(1306); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1305::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1306::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant63(__nt), __end)); (3, 125) } @@ -24376,11 +24467,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DoubleStarTypedParameter = Identifier => ActionFn(1306); + // DoubleStarTypedParameter = Identifier => ActionFn(1307); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1306::<>(source_code, mode, __sym0); + let __nt = super::__action1307::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant63(__nt), __end)); (1, 125) } @@ -24393,11 +24484,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DoubleStarTypedParameter? = DoubleStarTypedParameter => ActionFn(498); + // DoubleStarTypedParameter? = DoubleStarTypedParameter => ActionFn(501); let __sym0 = __pop_Variant63(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action498::<>(source_code, mode, __sym0); + let __nt = super::__action501::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant64(__nt), __end)); (1, 126) } @@ -24410,10 +24501,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DoubleStarTypedParameter? = => ActionFn(499); + // DoubleStarTypedParameter? = => ActionFn(502); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action499::<>(source_code, mode, &__start, &__end); + let __nt = super::__action502::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant64(__nt), __end)); (0, 126) } @@ -24426,7 +24517,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause = "except", Test<"all">, ":", Suite => ActionFn(1727); + // ExceptClause = "except", Test<"all">, ":", Suite => ActionFn(1731); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -24434,7 +24525,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1727::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1731::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant65(__nt), __end)); (4, 127) } @@ -24447,14 +24538,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause = "except", ":", Suite => ActionFn(1728); + // ExceptClause = "except", ":", Suite => ActionFn(1732); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1728::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1732::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant65(__nt), __end)); (3, 127) } @@ -24467,7 +24558,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause = "except", Test<"all">, "as", Identifier, ":", Suite => ActionFn(1203); + // ExceptClause = "except", Test<"all">, "as", Identifier, ":", Suite => ActionFn(1206); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -24477,7 +24568,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1203::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1206::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant65(__nt), __end)); (6, 127) } @@ -24490,11 +24581,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause+ = ExceptClause => ActionFn(330); + // ExceptClause+ = ExceptClause => ActionFn(335); let __sym0 = __pop_Variant65(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action330::<>(source_code, mode, __sym0); + let __nt = super::__action335::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant66(__nt), __end)); (1, 128) } @@ -24507,13 +24598,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause+ = ExceptClause+, ExceptClause => ActionFn(331); + // ExceptClause+ = ExceptClause+, ExceptClause => ActionFn(336); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant65(__symbols); let __sym0 = __pop_Variant66(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action331::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action336::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant66(__nt), __end)); (2, 128) } @@ -24526,7 +24617,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptStarClause = "except", "*", Test<"all">, ":", Suite => ActionFn(793); + // ExceptStarClause = "except", "*", Test<"all">, ":", Suite => ActionFn(794); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -24535,7 +24626,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action793::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action794::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant65(__nt), __end)); (5, 129) } @@ -24548,7 +24639,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptStarClause = "except", "*", Test<"all">, "as", Identifier, ":", Suite => ActionFn(1204); + // ExceptStarClause = "except", "*", Test<"all">, "as", Identifier, ":", Suite => ActionFn(1207); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -24559,7 +24650,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1204::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1207::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant65(__nt), __end)); (7, 129) } @@ -24572,11 +24663,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptStarClause+ = ExceptStarClause => ActionFn(325); + // ExceptStarClause+ = ExceptStarClause => ActionFn(330); let __sym0 = __pop_Variant65(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action325::<>(source_code, mode, __sym0); + let __nt = super::__action330::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant66(__nt), __end)); (1, 130) } @@ -24589,13 +24680,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptStarClause+ = ExceptStarClause+, ExceptStarClause => ActionFn(326); + // ExceptStarClause+ = ExceptStarClause+, ExceptStarClause => ActionFn(331); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant65(__symbols); let __sym0 = __pop_Variant66(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action326::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action331::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant66(__nt), __end)); (2, 130) } @@ -24608,14 +24699,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Expression<"all"> = Expression<"all">, "|", XorExpression<"all"> => ActionFn(1307); + // Expression<"all"> = Expression<"all">, "|", XorExpression<"all"> => ActionFn(1308); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1307::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1308::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 131) } @@ -24628,11 +24719,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Expression<"all"> = XorExpression<"all"> => ActionFn(372); + // Expression<"all"> = XorExpression<"all"> => ActionFn(375); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action372::<>(source_code, mode, __sym0); + let __nt = super::__action375::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 131) } @@ -24645,14 +24736,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Expression<"no-withitems"> = Expression<"all">, "|", XorExpression<"all"> => ActionFn(1308); + // Expression<"no-withitems"> = Expression<"all">, "|", XorExpression<"all"> => ActionFn(1309); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1308::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1309::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 132) } @@ -24665,11 +24756,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Expression<"no-withitems"> = XorExpression<"no-withitems"> => ActionFn(526); + // Expression<"no-withitems"> = XorExpression<"no-withitems"> => ActionFn(529); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action526::<>(source_code, mode, __sym0); + let __nt = super::__action529::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 132) } @@ -24682,11 +24773,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionList = GenericList => ActionFn(230); + // ExpressionList = GenericList => ActionFn(233); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action230::<>(source_code, mode, __sym0); + let __nt = super::__action233::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 133) } @@ -24699,13 +24790,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionList2 = OneOrMore, "," => ActionFn(614); + // ExpressionList2 = OneOrMore, "," => ActionFn(617); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action614::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action617::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (2, 134) } @@ -24718,11 +24809,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionList2 = OneOrMore => ActionFn(615); + // ExpressionList2 = OneOrMore => ActionFn(618); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action615::<>(source_code, mode, __sym0); + let __nt = super::__action618::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (1, 134) } @@ -24735,11 +24826,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionNoCond = OrTest<"all"> => ActionFn(236); + // ExpressionNoCond = OrTest<"all"> => ActionFn(239); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action236::<>(source_code, mode, __sym0); + let __nt = super::__action239::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 135) } @@ -24752,11 +24843,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionOrStarExpression = Expression<"all"> => ActionFn(228); + // ExpressionOrStarExpression = Expression<"all"> => ActionFn(231); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action228::<>(source_code, mode, __sym0); + let __nt = super::__action231::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 136) } @@ -24769,11 +24860,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionOrStarExpression = StarExpr => ActionFn(229); + // ExpressionOrStarExpression = StarExpr => ActionFn(232); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action229::<>(source_code, mode, __sym0); + let __nt = super::__action232::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 136) } @@ -24786,11 +24877,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringConversion? = FStringConversion => ActionFn(266); + // FStringConversion? = FStringConversion => ActionFn(269); let __sym0 = __pop_Variant67(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action266::<>(source_code, mode, __sym0); + let __nt = super::__action269::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant68(__nt), __end)); (1, 139) } @@ -24803,10 +24894,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringConversion? = => ActionFn(267); + // FStringConversion? = => ActionFn(270); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action267::<>(source_code, mode, &__start, &__end); + let __nt = super::__action270::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant68(__nt), __end)); (0, 139) } @@ -24819,13 +24910,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringExpr = FStringStart, FStringEnd => ActionFn(1585); + // FStringExpr = FStringStart, FStringEnd => ActionFn(1589); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1585::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1589::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant69(__nt), __end)); (2, 140) } @@ -24838,14 +24929,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringExpr = FStringStart, FStringMiddlePattern+, FStringEnd => ActionFn(1586); + // FStringExpr = FStringStart, FStringMiddlePattern+, FStringEnd => ActionFn(1590); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant70(__symbols); + let __sym1 = __pop_Variant73(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1586::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1590::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant69(__nt), __end)); (3, 140) } @@ -24858,11 +24949,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringFormatSpec = => ActionFn(1587); + // FStringFormatSpec = => ActionFn(1591); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action1587::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + let __nt = super::__action1591::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant70(__nt), __end)); (0, 141) } pub(crate) fn __reduce368< @@ -24874,12 +24965,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringFormatSpec = FStringMiddlePattern+ => ActionFn(1588); - let __sym0 = __pop_Variant70(__symbols); + // FStringFormatSpec = FStringMiddlePattern+ => ActionFn(1592); + let __sym0 = __pop_Variant73(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1588::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + let __nt = super::__action1592::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant70(__nt), __end)); (1, 141) } pub(crate) fn __reduce369< @@ -24891,14 +24982,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringFormatSpecSuffix = ":", FStringFormatSpec => ActionFn(219); + // FStringFormatSpecSuffix = ":", FStringFormatSpec => ActionFn(222); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant44(__symbols); + let __sym1 = __pop_Variant70(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action219::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + let __nt = super::__action222::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant70(__nt), __end)); (2, 142) } pub(crate) fn __reduce370< @@ -24910,12 +25001,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringFormatSpecSuffix? = FStringFormatSpecSuffix => ActionFn(264); - let __sym0 = __pop_Variant44(__symbols); + // FStringFormatSpecSuffix? = FStringFormatSpecSuffix => ActionFn(267); + let __sym0 = __pop_Variant70(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action264::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); + let __nt = super::__action267::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant71(__nt), __end)); (1, 143) } pub(crate) fn __reduce371< @@ -24927,11 +25018,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringFormatSpecSuffix? = => ActionFn(265); + // FStringFormatSpecSuffix? = => ActionFn(268); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action265::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); + let __nt = super::__action268::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant71(__nt), __end)); (0, 143) } pub(crate) fn __reduce372< @@ -24943,12 +25034,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringMiddlePattern = FStringReplacementField => ActionFn(216); - let __sym0 = __pop_Variant44(__symbols); + // FStringMiddlePattern = FStringReplacementField => ActionFn(219); + let __sym0 = __pop_Variant72(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action216::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + let __nt = super::__action219::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); (1, 144) } pub(crate) fn __reduce374< @@ -24960,11 +25051,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringMiddlePattern* = => ActionFn(270); + // FStringMiddlePattern* = => ActionFn(273); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action270::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + let __nt = super::__action273::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant73(__nt), __end)); (0, 145) } pub(crate) fn __reduce375< @@ -24976,12 +25067,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringMiddlePattern* = FStringMiddlePattern+ => ActionFn(271); - let __sym0 = __pop_Variant70(__symbols); + // FStringMiddlePattern* = FStringMiddlePattern+ => ActionFn(274); + let __sym0 = __pop_Variant73(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action271::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + let __nt = super::__action274::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant73(__nt), __end)); (1, 145) } pub(crate) fn __reduce376< @@ -24993,12 +25084,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringMiddlePattern+ = FStringMiddlePattern => ActionFn(453); - let __sym0 = __pop_Variant44(__symbols); + // FStringMiddlePattern+ = FStringMiddlePattern => ActionFn(456); + let __sym0 = __pop_Variant72(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action453::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + let __nt = super::__action456::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant73(__nt), __end)); (1, 146) } pub(crate) fn __reduce377< @@ -25010,14 +25101,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FStringMiddlePattern+ = FStringMiddlePattern+, FStringMiddlePattern => ActionFn(454); + // FStringMiddlePattern+ = FStringMiddlePattern+, FStringMiddlePattern => ActionFn(457); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant44(__symbols); - let __sym0 = __pop_Variant70(__symbols); + let __sym1 = __pop_Variant72(__symbols); + let __sym0 = __pop_Variant73(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action454::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + let __nt = super::__action457::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant73(__nt), __end)); (2, 146) } pub(crate) fn __reduce386< @@ -25029,13 +25120,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Factor<"all"> = UnaryOp, Factor<"all"> => ActionFn(1316); + // Factor<"all"> = UnaryOp, Factor<"all"> => ActionFn(1318); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); - let __sym0 = __pop_Variant100(__symbols); + let __sym0 = __pop_Variant103(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1316::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1318::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 148) } @@ -25048,11 +25139,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Factor<"all"> = Power<"all"> => ActionFn(528); + // Factor<"all"> = Power<"all"> => ActionFn(531); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action528::<>(source_code, mode, __sym0); + let __nt = super::__action531::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 148) } @@ -25065,13 +25156,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Factor<"no-withitems"> = UnaryOp, Factor<"all"> => ActionFn(1317); + // Factor<"no-withitems"> = UnaryOp, Factor<"all"> => ActionFn(1319); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); - let __sym0 = __pop_Variant100(__symbols); + let __sym0 = __pop_Variant103(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1317::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1319::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 149) } @@ -25084,11 +25175,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Factor<"no-withitems"> = Power<"no-withitems"> => ActionFn(577); + // Factor<"no-withitems"> = Power<"no-withitems"> => ActionFn(580); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action577::<>(source_code, mode, __sym0); + let __nt = super::__action580::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 149) } @@ -25101,11 +25192,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = "break" => ActionFn(1318); + // FlowStatement = "break" => ActionFn(1320); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1318::<>(source_code, mode, __sym0); + let __nt = super::__action1320::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 150) } @@ -25118,11 +25209,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = "continue" => ActionFn(1319); + // FlowStatement = "continue" => ActionFn(1321); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1319::<>(source_code, mode, __sym0); + let __nt = super::__action1321::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 150) } @@ -25135,13 +25226,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = "return", GenericList => ActionFn(1748); + // FlowStatement = "return", GenericList => ActionFn(1752); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1748::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1752::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (2, 150) } @@ -25154,11 +25245,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = "return" => ActionFn(1749); + // FlowStatement = "return" => ActionFn(1753); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1749::<>(source_code, mode, __sym0); + let __nt = super::__action1753::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 150) } @@ -25171,11 +25262,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = YieldExpr => ActionFn(1321); + // FlowStatement = YieldExpr => ActionFn(1323); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1321::<>(source_code, mode, __sym0); + let __nt = super::__action1323::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 150) } @@ -25205,7 +25296,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ForStatement = "async", "for", ExpressionList, "in", GenericList, ":", Suite, "else", ":", Suite => ActionFn(1739); + // ForStatement = "async", "for", ExpressionList, "in", GenericList, ":", Suite, "else", ":", Suite => ActionFn(1743); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant25(__symbols); let __sym8 = __pop_Variant0(__symbols); @@ -25219,7 +25310,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = super::__action1739::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); + let __nt = super::__action1743::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (10, 151) } @@ -25232,7 +25323,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ForStatement = "async", "for", ExpressionList, "in", GenericList, ":", Suite => ActionFn(1740); + // ForStatement = "async", "for", ExpressionList, "in", GenericList, ":", Suite => ActionFn(1744); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -25243,7 +25334,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1740::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1744::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 151) } @@ -25256,7 +25347,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ForStatement = "for", ExpressionList, "in", GenericList, ":", Suite, "else", ":", Suite => ActionFn(1741); + // ForStatement = "for", ExpressionList, "in", GenericList, ":", Suite, "else", ":", Suite => ActionFn(1745); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant25(__symbols); let __sym7 = __pop_Variant0(__symbols); @@ -25269,7 +25360,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = super::__action1741::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); + let __nt = super::__action1745::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (9, 151) } @@ -25282,7 +25373,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ForStatement = "for", ExpressionList, "in", GenericList, ":", Suite => ActionFn(1742); + // ForStatement = "for", ExpressionList, "in", GenericList, ":", Suite => ActionFn(1746); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -25292,7 +25383,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1742::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1746::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (6, 151) } @@ -25305,20 +25396,20 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "async", "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1763); + // FuncDef = "async", "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1767); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant25(__symbols); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant15(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant46(__symbols); - let __sym3 = __pop_Variant98(__symbols); + let __sym3 = __pop_Variant101(__symbols); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = super::__action1763::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); + let __nt = super::__action1767::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (9, 152) } @@ -25331,7 +25422,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "async", "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1764); + // FuncDef = "async", "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1768); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -25343,7 +25434,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1764::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + let __nt = super::__action1768::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (8, 152) } @@ -25356,21 +25447,21 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "async", "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1765); + // FuncDef = Decorator+, "async", "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1769); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant25(__symbols); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant15(__symbols); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant46(__symbols); - let __sym4 = __pop_Variant98(__symbols); + let __sym4 = __pop_Variant101(__symbols); let __sym3 = __pop_Variant23(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = super::__action1765::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); + let __nt = super::__action1769::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (10, 152) } @@ -25383,7 +25474,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "async", "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1766); + // FuncDef = Decorator+, "async", "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1770); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant25(__symbols); let __sym7 = __pop_Variant0(__symbols); @@ -25396,7 +25487,7 @@ mod __parse__Top { let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = super::__action1766::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); + let __nt = super::__action1770::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (9, 152) } @@ -25409,18 +25500,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "async", "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1767); + // FuncDef = "async", "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1771); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant46(__symbols); - let __sym3 = __pop_Variant98(__symbols); + let __sym3 = __pop_Variant101(__symbols); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1767::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1771::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 152) } @@ -25433,7 +25524,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "async", "def", Identifier, Parameters, ":", Suite => ActionFn(1768); + // FuncDef = "async", "def", Identifier, Parameters, ":", Suite => ActionFn(1772); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -25443,7 +25534,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1768::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1772::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (6, 152) } @@ -25456,19 +25547,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "async", "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1769); + // FuncDef = Decorator+, "async", "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1773); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant46(__symbols); - let __sym4 = __pop_Variant98(__symbols); + let __sym4 = __pop_Variant101(__symbols); let __sym3 = __pop_Variant23(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1769::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + let __nt = super::__action1773::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (8, 152) } @@ -25481,7 +25572,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "async", "def", Identifier, Parameters, ":", Suite => ActionFn(1770); + // FuncDef = Decorator+, "async", "def", Identifier, Parameters, ":", Suite => ActionFn(1774); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -25492,7 +25583,7 @@ mod __parse__Top { let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1770::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1774::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 152) } @@ -25505,19 +25596,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1771); + // FuncDef = "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1775); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant15(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant46(__symbols); - let __sym2 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant101(__symbols); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1771::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + let __nt = super::__action1775::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (8, 152) } @@ -25530,7 +25621,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1772); + // FuncDef = "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1776); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -25541,7 +25632,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1772::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1776::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 152) } @@ -25554,20 +25645,20 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1773); + // FuncDef = Decorator+, "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1777); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant25(__symbols); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant15(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant46(__symbols); - let __sym3 = __pop_Variant98(__symbols); + let __sym3 = __pop_Variant101(__symbols); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = super::__action1773::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); + let __nt = super::__action1777::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (9, 152) } @@ -25580,7 +25671,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1774); + // FuncDef = Decorator+, "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1778); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -25592,7 +25683,7 @@ mod __parse__Top { let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1774::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + let __nt = super::__action1778::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (8, 152) } @@ -25605,17 +25696,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1775); + // FuncDef = "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1779); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant46(__symbols); - let __sym2 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant101(__symbols); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1775::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1779::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (6, 152) } @@ -25628,7 +25719,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "def", Identifier, Parameters, ":", Suite => ActionFn(1776); + // FuncDef = "def", Identifier, Parameters, ":", Suite => ActionFn(1780); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -25637,7 +25728,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1776::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1780::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (5, 152) } @@ -25650,18 +25741,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1777); + // FuncDef = Decorator+, "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1781); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant46(__symbols); - let __sym3 = __pop_Variant98(__symbols); + let __sym3 = __pop_Variant101(__symbols); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1777::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1781::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 152) } @@ -25674,7 +25765,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "def", Identifier, Parameters, ":", Suite => ActionFn(1778); + // FuncDef = Decorator+, "def", Identifier, Parameters, ":", Suite => ActionFn(1782); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -25684,7 +25775,7 @@ mod __parse__Top { let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1778::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1782::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (6, 152) } @@ -25697,13 +25788,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = NamedExpressionTest, CompFor => ActionFn(1549); + // FunctionArgument = NamedExpressionTest, CompFor => ActionFn(1553); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant54(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1549::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1553::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant31(__nt), __end)); (2, 153) } @@ -25716,11 +25807,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = NamedExpressionTest => ActionFn(1550); + // FunctionArgument = NamedExpressionTest => ActionFn(1554); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1550::<>(source_code, mode, __sym0); + let __nt = super::__action1554::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant31(__nt), __end)); (1, 153) } @@ -25733,14 +25824,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = Identifier, "=", Test<"all"> => ActionFn(1323); + // FunctionArgument = Identifier, "=", Test<"all"> => ActionFn(1325); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1323::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1325::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant31(__nt), __end)); (3, 153) } @@ -25753,13 +25844,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = "*", Test<"all"> => ActionFn(1324); + // FunctionArgument = "*", Test<"all"> => ActionFn(1326); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1324::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1326::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant31(__nt), __end)); (2, 153) } @@ -25772,13 +25863,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = "**", Test<"all"> => ActionFn(1325); + // FunctionArgument = "**", Test<"all"> => ActionFn(1327); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1325::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1327::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant31(__nt), __end)); (2, 153) } @@ -25791,12 +25882,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument? = FunctionArgument => ActionFn(464); + // FunctionArgument? = FunctionArgument => ActionFn(467); let __sym0 = __pop_Variant31(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action464::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); + let __nt = super::__action467::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); (1, 154) } pub(crate) fn __reduce422< @@ -25808,11 +25899,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument? = => ActionFn(465); + // FunctionArgument? = => ActionFn(468); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action465::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); + let __nt = super::__action468::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); (0, 154) } pub(crate) fn __reduce423< @@ -25824,13 +25915,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GenericList = OneOrMore, "," => ActionFn(1326); + // GenericList = OneOrMore, "," => ActionFn(1328); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1326::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1328::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 155) } @@ -25843,11 +25934,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GenericList = OneOrMore => ActionFn(1327); + // GenericList = OneOrMore => ActionFn(1329); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1327::<>(source_code, mode, __sym0); + let __nt = super::__action1329::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 155) } @@ -25860,13 +25951,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GenericList = OneOrMore, "," => ActionFn(1328); + // GenericList = OneOrMore, "," => ActionFn(1330); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1328::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1330::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 156) } @@ -25879,11 +25970,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GenericList = OneOrMore => ActionFn(1329); + // GenericList = OneOrMore => ActionFn(1331); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1329::<>(source_code, mode, __sym0); + let __nt = super::__action1331::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 156) } @@ -25896,13 +25987,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GlobalStatement = "global", OneOrMore => ActionFn(1330); + // GlobalStatement = "global", OneOrMore => ActionFn(1332); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant82(__symbols); + let __sym1 = __pop_Variant85(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1330::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1332::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (2, 157) } @@ -25934,11 +26025,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Identifier = name => ActionFn(1331); + // Identifier = name => ActionFn(1333); let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1331::<>(source_code, mode, __sym0); + let __nt = super::__action1333::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant23(__nt), __end)); (1, 159) } @@ -25951,7 +26042,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // IfStatement = "if", NamedExpressionTest, ":", Suite, "else", ":", Suite => ActionFn(1152); + // IfStatement = "if", NamedExpressionTest, ":", Suite, "else", ":", Suite => ActionFn(1155); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -25962,7 +26053,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1152::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1155::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 160) } @@ -25975,7 +26066,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // IfStatement = "if", NamedExpressionTest, ":", Suite => ActionFn(1153); + // IfStatement = "if", NamedExpressionTest, ":", Suite => ActionFn(1156); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -25983,7 +26074,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1153::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1156::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (4, 160) } @@ -25996,7 +26087,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // IfStatement = "if", NamedExpressionTest, ":", Suite, (<@L> "elif" ":" )+, "else", ":", Suite => ActionFn(1154); + // IfStatement = "if", NamedExpressionTest, ":", Suite, (<@L> "elif" ":" )+, "else", ":", Suite => ActionFn(1157); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); @@ -26008,7 +26099,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1154::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + let __nt = super::__action1157::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (8, 160) } @@ -26021,7 +26112,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // IfStatement = "if", NamedExpressionTest, ":", Suite, (<@L> "elif" ":" )+ => ActionFn(1155); + // IfStatement = "if", NamedExpressionTest, ":", Suite, (<@L> "elif" ":" )+ => ActionFn(1158); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant28(__symbols); let __sym3 = __pop_Variant25(__symbols); @@ -26030,7 +26121,7 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1155::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1158::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (5, 160) } @@ -26043,15 +26134,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsAlias = DottedName, "as", Identifier => ActionFn(1332); + // ImportAsAlias = DottedName, "as", Identifier => ActionFn(1334); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1332::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant72(__nt), __end)); + let __nt = super::__action1334::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant75(__nt), __end)); (3, 161) } pub(crate) fn __reduce435< @@ -26063,12 +26154,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsAlias = DottedName => ActionFn(1333); + // ImportAsAlias = DottedName => ActionFn(1335); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1333::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant72(__nt), __end)); + let __nt = super::__action1335::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant75(__nt), __end)); (1, 161) } pub(crate) fn __reduce436< @@ -26080,15 +26171,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsAlias = Identifier, "as", Identifier => ActionFn(1334); + // ImportAsAlias = Identifier, "as", Identifier => ActionFn(1336); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1334::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant72(__nt), __end)); + let __nt = super::__action1336::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant75(__nt), __end)); (3, 162) } pub(crate) fn __reduce437< @@ -26100,12 +26191,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsAlias = Identifier => ActionFn(1335); + // ImportAsAlias = Identifier => ActionFn(1337); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1335::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant72(__nt), __end)); + let __nt = super::__action1337::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant75(__nt), __end)); (1, 162) } pub(crate) fn __reduce438< @@ -26117,12 +26208,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsNames = OneOrMore> => ActionFn(1336); - let __sym0 = __pop_Variant73(__symbols); + // ImportAsNames = OneOrMore> => ActionFn(1338); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1336::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1338::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (1, 163) } pub(crate) fn __reduce439< @@ -26134,16 +26225,16 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsNames = "(", OneOrMore>, ",", ")" => ActionFn(1337); + // ImportAsNames = "(", OneOrMore>, ",", ")" => ActionFn(1339); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant73(__symbols); + let __sym1 = __pop_Variant76(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1337::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1339::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (4, 163) } pub(crate) fn __reduce440< @@ -26155,15 +26246,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsNames = "(", OneOrMore>, ")" => ActionFn(1338); + // ImportAsNames = "(", OneOrMore>, ")" => ActionFn(1340); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant73(__symbols); + let __sym1 = __pop_Variant76(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1338::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1340::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (3, 163) } pub(crate) fn __reduce441< @@ -26175,12 +26266,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsNames = "*" => ActionFn(1339); + // ImportAsNames = "*" => ActionFn(1341); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1339::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1341::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (1, 163) } pub(crate) fn __reduce442< @@ -26197,7 +26288,7 @@ mod __parse__Top { let __start = __sym0.0; let __end = __sym0.2; let __nt = super::__action64::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + __symbols.push((__start, __Symbol::Variant77(__nt), __end)); (1, 164) } pub(crate) fn __reduce443< @@ -26214,7 +26305,7 @@ mod __parse__Top { let __start = __sym0.0; let __end = __sym0.2; let __nt = super::__action65::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + __symbols.push((__start, __Symbol::Variant77(__nt), __end)); (1, 164) } pub(crate) fn __reduce444< @@ -26226,11 +26317,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportDots* = => ActionFn(388); + // ImportDots* = => ActionFn(391); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action388::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant75(__nt), __end)); + let __nt = super::__action391::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant78(__nt), __end)); (0, 165) } pub(crate) fn __reduce445< @@ -26242,12 +26333,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportDots* = ImportDots+ => ActionFn(389); - let __sym0 = __pop_Variant75(__symbols); + // ImportDots* = ImportDots+ => ActionFn(392); + let __sym0 = __pop_Variant78(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action389::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant75(__nt), __end)); + let __nt = super::__action392::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant78(__nt), __end)); (1, 165) } pub(crate) fn __reduce446< @@ -26259,12 +26350,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportDots+ = ImportDots => ActionFn(386); - let __sym0 = __pop_Variant74(__symbols); + // ImportDots+ = ImportDots => ActionFn(389); + let __sym0 = __pop_Variant77(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action386::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant75(__nt), __end)); + let __nt = super::__action389::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant78(__nt), __end)); (1, 166) } pub(crate) fn __reduce447< @@ -26276,14 +26367,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportDots+ = ImportDots+, ImportDots => ActionFn(387); + // ImportDots+ = ImportDots+, ImportDots => ActionFn(390); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant74(__symbols); - let __sym0 = __pop_Variant75(__symbols); + let __sym1 = __pop_Variant77(__symbols); + let __sym0 = __pop_Variant78(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action387::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant75(__nt), __end)); + let __nt = super::__action390::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant78(__nt), __end)); (2, 166) } pub(crate) fn __reduce448< @@ -26295,12 +26386,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportFromLocation = DottedName => ActionFn(1597); + // ImportFromLocation = DottedName => ActionFn(1601); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1597::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant76(__nt), __end)); + let __nt = super::__action1601::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant79(__nt), __end)); (1, 167) } pub(crate) fn __reduce449< @@ -26312,14 +26403,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportFromLocation = ImportDots+, DottedName => ActionFn(1598); + // ImportFromLocation = ImportDots+, DottedName => ActionFn(1602); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant23(__symbols); - let __sym0 = __pop_Variant75(__symbols); + let __sym0 = __pop_Variant78(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1598::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant76(__nt), __end)); + let __nt = super::__action1602::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant79(__nt), __end)); (2, 167) } pub(crate) fn __reduce450< @@ -26332,11 +26423,11 @@ mod __parse__Top { ) -> (usize, usize) { // ImportFromLocation = ImportDots+ => ActionFn(63); - let __sym0 = __pop_Variant75(__symbols); + let __sym0 = __pop_Variant78(__symbols); let __start = __sym0.0; let __end = __sym0.2; let __nt = super::__action63::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant76(__nt), __end)); + __symbols.push((__start, __Symbol::Variant79(__nt), __end)); (1, 167) } pub(crate) fn __reduce451< @@ -26348,13 +26439,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportStatement = "import", OneOrMore> => ActionFn(1340); + // ImportStatement = "import", OneOrMore> => ActionFn(1342); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant73(__symbols); + let __sym1 = __pop_Variant76(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1340::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1342::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (2, 168) } @@ -26367,15 +26458,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportStatement = "from", ImportFromLocation, "import", ImportAsNames => ActionFn(1341); + // ImportStatement = "from", ImportFromLocation, "import", ImportAsNames => ActionFn(1343); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant73(__symbols); + let __sym3 = __pop_Variant76(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant76(__symbols); + let __sym1 = __pop_Variant79(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1341::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1343::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (4, 168) } @@ -26388,13 +26479,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // KwargParameter = "**", DoubleStarTypedParameter => ActionFn(1571); + // KwargParameter = "**", DoubleStarTypedParameter => ActionFn(1575); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1571::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1575::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); (2, 172) } @@ -26407,11 +26498,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // KwargParameter = "**" => ActionFn(1572); + // KwargParameter = "**" => ActionFn(1576); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1572::<>(source_code, mode, __sym0); + let __nt = super::__action1576::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); (1, 172) } @@ -26424,13 +26515,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // KwargParameter = "**", StarUntypedParameter => ActionFn(1016); + // KwargParameter = "**", StarUntypedParameter => ActionFn(1019); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant63(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1016::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1019::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); (2, 173) } @@ -26443,11 +26534,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // KwargParameter = "**" => ActionFn(1017); + // KwargParameter = "**" => ActionFn(1020); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1017::<>(source_code, mode, __sym0); + let __nt = super::__action1020::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); (1, 173) } @@ -26460,13 +26551,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ListLiteralValues = OneOrMore, "," => ActionFn(622); + // ListLiteralValues = OneOrMore, "," => ActionFn(625); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action622::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action625::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (2, 175) } @@ -26479,11 +26570,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ListLiteralValues = OneOrMore => ActionFn(623); + // ListLiteralValues = OneOrMore => ActionFn(626); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action623::<>(source_code, mode, __sym0); + let __nt = super::__action626::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (1, 175) } @@ -26496,11 +26587,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ListLiteralValues? = ListLiteralValues => ActionFn(572); + // ListLiteralValues? = ListLiteralValues => ActionFn(575); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action572::<>(source_code, mode, __sym0); + let __nt = super::__action575::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant34(__nt), __end)); (1, 176) } @@ -26513,10 +26604,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ListLiteralValues? = => ActionFn(573); + // ListLiteralValues? = => ActionFn(576); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action573::<>(source_code, mode, &__start, &__end); + let __nt = super::__action576::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant34(__nt), __end)); (0, 176) } @@ -26529,11 +26620,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = "None" => ActionFn(1346); + // LiteralPattern = "None" => ActionFn(1348); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1346::<>(source_code, mode, __sym0); + let __nt = super::__action1348::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 177) } @@ -26546,11 +26637,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = "True" => ActionFn(1347); + // LiteralPattern = "True" => ActionFn(1349); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1347::<>(source_code, mode, __sym0); + let __nt = super::__action1349::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 177) } @@ -26563,11 +26654,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = "False" => ActionFn(1348); + // LiteralPattern = "False" => ActionFn(1350); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1348::<>(source_code, mode, __sym0); + let __nt = super::__action1350::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 177) } @@ -26580,11 +26671,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = NumberExpr => ActionFn(1349); + // LiteralPattern = NumberExpr => ActionFn(1351); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1349::<>(source_code, mode, __sym0); + let __nt = super::__action1351::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 177) } @@ -26597,15 +26688,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = AddOpExpr => ActionFn(1350); + // LiteralPattern = AddOpExpr => ActionFn(1352); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1350::<>(source_code, mode, __sym0); + let __nt = super::__action1352::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 177) } - pub(crate) fn __reduce474< + pub(crate) fn __reduce473< >( source_code: &str, mode: Mode, @@ -26614,13 +26705,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = MatchNameOrAttr => ActionFn(126); - let __sym0 = __pop_Variant44(__symbols); + // LiteralPattern = StringLiteral => ActionFn(1353); + let __sym0 = __pop_Variant69(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action126::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); - (1, 178) + let __nt = super::__action1353::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 177) } pub(crate) fn __reduce475< >( @@ -26631,8 +26722,8 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = NumberExpr => ActionFn(127); - let __sym0 = __pop_Variant15(__symbols); + // MappingKey = MatchNameOrAttr => ActionFn(127); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym0.2; let __nt = super::__action127::<>(source_code, mode, __sym0); @@ -26648,8 +26739,8 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = AddOpExpr => ActionFn(128); - let __sym0 = __pop_Variant15(__symbols); + // MappingKey = String => ActionFn(128); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym0.2; let __nt = super::__action128::<>(source_code, mode, __sym0); @@ -26665,11 +26756,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = "None" => ActionFn(1352); - let __sym0 = __pop_Variant0(__symbols); + // MappingKey = NumberExpr => ActionFn(129); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1352::<>(source_code, mode, __sym0); + let __nt = super::__action129::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); (1, 178) } @@ -26682,11 +26773,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = "True" => ActionFn(1353); - let __sym0 = __pop_Variant0(__symbols); + // MappingKey = AddOpExpr => ActionFn(130); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1353::<>(source_code, mode, __sym0); + let __nt = super::__action130::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); (1, 178) } @@ -26699,11 +26790,28 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = "False" => ActionFn(1354); + // MappingKey = "None" => ActionFn(1355); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action1355::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 178) + } + pub(crate) fn __reduce480< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // MappingKey = "True" => ActionFn(1356); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1354::<>(source_code, mode, __sym0); + let __nt = super::__action1356::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); (1, 178) } @@ -26716,17 +26824,34 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", "}" => ActionFn(1356); + // MappingKey = "False" => ActionFn(1357); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action1357::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 178) + } + pub(crate) fn __reduce482< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // MappingPattern = "{", "}" => ActionFn(1358); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1356::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1358::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 179) } - pub(crate) fn __reduce482< + pub(crate) fn __reduce483< >( source_code: &str, mode: Mode, @@ -26735,19 +26860,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", OneOrMore, ",", "}" => ActionFn(1357); + // MappingPattern = "{", OneOrMore, ",", "}" => ActionFn(1359); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant84(__symbols); + let __sym1 = __pop_Variant87(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1357::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1359::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (4, 179) } - pub(crate) fn __reduce483< + pub(crate) fn __reduce484< >( source_code: &str, mode: Mode, @@ -26756,18 +26881,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", OneOrMore, "}" => ActionFn(1358); + // MappingPattern = "{", OneOrMore, "}" => ActionFn(1360); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant84(__symbols); + let __sym1 = __pop_Variant87(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1358::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1360::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (3, 179) } - pub(crate) fn __reduce484< + pub(crate) fn __reduce485< >( source_code: &str, mode: Mode, @@ -26776,7 +26901,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", "**", Identifier, ",", "}" => ActionFn(1359); + // MappingPattern = "{", "**", Identifier, ",", "}" => ActionFn(1361); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -26785,11 +26910,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1359::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1361::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (5, 179) } - pub(crate) fn __reduce485< + pub(crate) fn __reduce486< >( source_code: &str, mode: Mode, @@ -26798,7 +26923,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", "**", Identifier, "}" => ActionFn(1360); + // MappingPattern = "{", "**", Identifier, "}" => ActionFn(1362); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant23(__symbols); @@ -26806,11 +26931,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1360::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1362::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (4, 179) } - pub(crate) fn __reduce486< + pub(crate) fn __reduce487< >( source_code: &str, mode: Mode, @@ -26819,22 +26944,22 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", OneOrMore, ",", "**", Identifier, ",", "}" => ActionFn(1361); + // MappingPattern = "{", OneOrMore, ",", "**", Identifier, ",", "}" => ActionFn(1363); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant84(__symbols); + let __sym1 = __pop_Variant87(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1361::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1363::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (7, 179) } - pub(crate) fn __reduce487< + pub(crate) fn __reduce488< >( source_code: &str, mode: Mode, @@ -26843,21 +26968,21 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", OneOrMore, ",", "**", Identifier, "}" => ActionFn(1362); + // MappingPattern = "{", OneOrMore, ",", "**", Identifier, "}" => ActionFn(1364); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant84(__symbols); + let __sym1 = __pop_Variant87(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1362::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1364::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (6, 179) } - pub(crate) fn __reduce488< + pub(crate) fn __reduce489< >( source_code: &str, mode: Mode, @@ -26866,7 +26991,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchCase = "case", Patterns, Guard, ":", Suite => ActionFn(1220); + // MatchCase = "case", Patterns, Guard, ":", Suite => ActionFn(1223); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -26875,11 +27000,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1220::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant77(__nt), __end)); + let __nt = super::__action1223::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant80(__nt), __end)); (5, 180) } - pub(crate) fn __reduce489< + pub(crate) fn __reduce490< >( source_code: &str, mode: Mode, @@ -26888,7 +27013,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchCase = "case", Patterns, ":", Suite => ActionFn(1221); + // MatchCase = "case", Patterns, ":", Suite => ActionFn(1224); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -26896,11 +27021,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1221::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant77(__nt), __end)); + let __nt = super::__action1224::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant80(__nt), __end)); (4, 180) } - pub(crate) fn __reduce490< + pub(crate) fn __reduce491< >( source_code: &str, mode: Mode, @@ -26909,15 +27034,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchCase+ = MatchCase => ActionFn(366); - let __sym0 = __pop_Variant77(__symbols); + // MatchCase+ = MatchCase => ActionFn(369); + let __sym0 = __pop_Variant80(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action366::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant78(__nt), __end)); + let __nt = super::__action369::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant81(__nt), __end)); (1, 181) } - pub(crate) fn __reduce491< + pub(crate) fn __reduce492< >( source_code: &str, mode: Mode, @@ -26926,17 +27051,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchCase+ = MatchCase+, MatchCase => ActionFn(367); + // MatchCase+ = MatchCase+, MatchCase => ActionFn(370); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant77(__symbols); - let __sym0 = __pop_Variant78(__symbols); + let __sym1 = __pop_Variant80(__symbols); + let __sym0 = __pop_Variant81(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action367::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant78(__nt), __end)); + let __nt = super::__action370::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant81(__nt), __end)); (2, 181) } - pub(crate) fn __reduce492< + pub(crate) fn __reduce493< >( source_code: &str, mode: Mode, @@ -26945,18 +27070,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchKeywordEntry = Identifier, "=", Pattern => ActionFn(1363); + // MatchKeywordEntry = Identifier, "=", Pattern => ActionFn(1365); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1363::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant79(__nt), __end)); + let __nt = super::__action1365::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant82(__nt), __end)); (3, 182) } - pub(crate) fn __reduce493< + pub(crate) fn __reduce494< >( source_code: &str, mode: Mode, @@ -26965,18 +27090,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchMappingEntry = MappingKey, ":", Pattern => ActionFn(133); + // MatchMappingEntry = MappingKey, ":", Pattern => ActionFn(134); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action133::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant80(__nt), __end)); + let __nt = super::__action134::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant83(__nt), __end)); (3, 183) } - pub(crate) fn __reduce494< + pub(crate) fn __reduce495< >( source_code: &str, mode: Mode, @@ -26985,15 +27110,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchName = Identifier => ActionFn(1364); + // MatchName = Identifier => ActionFn(1366); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1364::<>(source_code, mode, __sym0); + let __nt = super::__action1366::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); (1, 184) } - pub(crate) fn __reduce495< + pub(crate) fn __reduce496< >( source_code: &str, mode: Mode, @@ -27002,18 +27127,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchNameOrAttr = MatchName, ".", Identifier => ActionFn(1365); + // MatchNameOrAttr = MatchName, ".", Identifier => ActionFn(1367); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1365::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1367::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); (3, 185) } - pub(crate) fn __reduce496< + pub(crate) fn __reduce497< >( source_code: &str, mode: Mode, @@ -27022,18 +27147,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchNameOrAttr = MatchNameOrAttr, ".", Identifier => ActionFn(1366); + // MatchNameOrAttr = MatchNameOrAttr, ".", Identifier => ActionFn(1368); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1366::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1368::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); (3, 185) } - pub(crate) fn __reduce497< + pub(crate) fn __reduce498< >( source_code: &str, mode: Mode, @@ -27042,10 +27167,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchStatement = "match", TestOrStarNamedExpr, ":", "\n", Indent, MatchCase+, Dedent => ActionFn(861); + // MatchStatement = "match", TestOrStarNamedExpr, ":", "\n", Indent, MatchCase+, Dedent => ActionFn(862); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant78(__symbols); + let __sym5 = __pop_Variant81(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -27053,11 +27178,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action861::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action862::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 186) } - pub(crate) fn __reduce498< + pub(crate) fn __reduce499< >( source_code: &str, mode: Mode, @@ -27066,10 +27191,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchStatement = "match", TestOrStarNamedExpr, ",", ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1367); + // MatchStatement = "match", TestOrStarNamedExpr, ",", ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1369); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant78(__symbols); + let __sym6 = __pop_Variant81(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -27078,11 +27203,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1367::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + let __nt = super::__action1369::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (8, 186) } - pub(crate) fn __reduce499< + pub(crate) fn __reduce500< >( source_code: &str, mode: Mode, @@ -27091,10 +27216,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchStatement = "match", TwoOrMore, ",", ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1368); + // MatchStatement = "match", TwoOrMoreSep, ",", ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1370); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant78(__symbols); + let __sym6 = __pop_Variant81(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -27103,11 +27228,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1368::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + let __nt = super::__action1370::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (8, 186) } - pub(crate) fn __reduce500< + pub(crate) fn __reduce501< >( source_code: &str, mode: Mode, @@ -27116,10 +27241,10 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchStatement = "match", TwoOrMore, ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1369); + // MatchStatement = "match", TwoOrMoreSep, ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1371); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant78(__symbols); + let __sym5 = __pop_Variant81(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -27127,11 +27252,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1369::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1371::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (7, 186) } - pub(crate) fn __reduce501< + pub(crate) fn __reduce502< >( source_code: &str, mode: Mode, @@ -27140,15 +27265,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MulOp = "*" => ActionFn(198); + // MulOp = "*" => ActionFn(199); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action198::<>(source_code, mode, __sym0); + let __nt = super::__action199::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 187) } - pub(crate) fn __reduce502< + pub(crate) fn __reduce503< >( source_code: &str, mode: Mode, @@ -27157,15 +27282,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MulOp = "/" => ActionFn(199); + // MulOp = "/" => ActionFn(200); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action199::<>(source_code, mode, __sym0); + let __nt = super::__action200::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 187) } - pub(crate) fn __reduce503< + pub(crate) fn __reduce504< >( source_code: &str, mode: Mode, @@ -27174,15 +27299,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MulOp = "//" => ActionFn(200); + // MulOp = "//" => ActionFn(201); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action200::<>(source_code, mode, __sym0); + let __nt = super::__action201::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 187) } - pub(crate) fn __reduce504< + pub(crate) fn __reduce505< >( source_code: &str, mode: Mode, @@ -27191,15 +27316,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MulOp = "%" => ActionFn(201); + // MulOp = "%" => ActionFn(202); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action201::<>(source_code, mode, __sym0); + let __nt = super::__action202::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 187) } - pub(crate) fn __reduce505< + pub(crate) fn __reduce506< >( source_code: &str, mode: Mode, @@ -27208,15 +27333,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MulOp = "@" => ActionFn(202); + // MulOp = "@" => ActionFn(203); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action202::<>(source_code, mode, __sym0); + let __nt = super::__action203::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 187) } - pub(crate) fn __reduce506< + pub(crate) fn __reduce507< >( source_code: &str, mode: Mode, @@ -27225,18 +27350,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NamedExpression = NamedExpressionName, ":=", Test<"all"> => ActionFn(1370); + // NamedExpression = NamedExpressionName, ":=", Test<"all"> => ActionFn(1372); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1370::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1372::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 188) } - pub(crate) fn __reduce507< + pub(crate) fn __reduce508< >( source_code: &str, mode: Mode, @@ -27245,15 +27370,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NamedExpressionName = Identifier => ActionFn(1371); + // NamedExpressionName = Identifier => ActionFn(1373); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1371::<>(source_code, mode, __sym0); + let __nt = super::__action1373::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 189) } - pub(crate) fn __reduce508< + pub(crate) fn __reduce509< >( source_code: &str, mode: Mode, @@ -27262,15 +27387,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NamedExpressionTest = NamedExpression => ActionFn(179); + // NamedExpressionTest = NamedExpression => ActionFn(180); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action179::<>(source_code, mode, __sym0); + let __nt = super::__action180::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 190) } - pub(crate) fn __reduce509< + pub(crate) fn __reduce510< >( source_code: &str, mode: Mode, @@ -27279,15 +27404,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NamedExpressionTest = Test<"all"> => ActionFn(180); + // NamedExpressionTest = Test<"all"> => ActionFn(181); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action180::<>(source_code, mode, __sym0); + let __nt = super::__action181::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 190) } - pub(crate) fn __reduce510< + pub(crate) fn __reduce511< >( source_code: &str, mode: Mode, @@ -27304,7 +27429,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 191) } - pub(crate) fn __reduce511< + pub(crate) fn __reduce512< >( source_code: &str, mode: Mode, @@ -27321,7 +27446,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 191) } - pub(crate) fn __reduce512< + pub(crate) fn __reduce513< >( source_code: &str, mode: Mode, @@ -27330,17 +27455,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NonlocalStatement = "nonlocal", OneOrMore => ActionFn(1372); + // NonlocalStatement = "nonlocal", OneOrMore => ActionFn(1374); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant82(__symbols); + let __sym1 = __pop_Variant85(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1372::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1374::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (2, 192) } - pub(crate) fn __reduce513< + pub(crate) fn __reduce514< >( source_code: &str, mode: Mode, @@ -27349,17 +27474,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NotTest<"all"> = "not", NotTest<"all"> => ActionFn(1373); + // NotTest<"all"> = "not", NotTest<"all"> => ActionFn(1375); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1373::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1375::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 193) } - pub(crate) fn __reduce514< + pub(crate) fn __reduce515< >( source_code: &str, mode: Mode, @@ -27368,15 +27493,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NotTest<"all"> = Comparison<"all"> => ActionFn(475); + // NotTest<"all"> = Comparison<"all"> => ActionFn(478); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action475::<>(source_code, mode, __sym0); + let __nt = super::__action478::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 193) } - pub(crate) fn __reduce515< + pub(crate) fn __reduce516< >( source_code: &str, mode: Mode, @@ -27385,17 +27510,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NotTest<"no-withitems"> = "not", NotTest<"all"> => ActionFn(1374); + // NotTest<"no-withitems"> = "not", NotTest<"all"> => ActionFn(1376); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1374::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1376::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 194) } - pub(crate) fn __reduce516< + pub(crate) fn __reduce517< >( source_code: &str, mode: Mode, @@ -27404,15 +27529,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NotTest<"no-withitems"> = Comparison<"no-withitems"> => ActionFn(518); + // NotTest<"no-withitems"> = Comparison<"no-withitems"> => ActionFn(521); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action518::<>(source_code, mode, __sym0); + let __nt = super::__action521::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 194) } - pub(crate) fn __reduce517< + pub(crate) fn __reduce518< >( source_code: &str, mode: Mode, @@ -27421,15 +27546,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Number = int => ActionFn(243); + // Number = int => ActionFn(246); let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action243::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant81(__nt), __end)); + let __nt = super::__action246::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant84(__nt), __end)); (1, 195) } - pub(crate) fn __reduce518< + pub(crate) fn __reduce519< >( source_code: &str, mode: Mode, @@ -27438,15 +27563,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Number = float => ActionFn(244); + // Number = float => ActionFn(247); let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action244::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant81(__nt), __end)); + let __nt = super::__action247::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant84(__nt), __end)); (1, 195) } - pub(crate) fn __reduce519< + pub(crate) fn __reduce520< >( source_code: &str, mode: Mode, @@ -27455,15 +27580,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Number = complex => ActionFn(245); + // Number = complex => ActionFn(248); let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action245::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant81(__nt), __end)); + let __nt = super::__action248::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant84(__nt), __end)); (1, 195) } - pub(crate) fn __reduce520< + pub(crate) fn __reduce521< >( source_code: &str, mode: Mode, @@ -27472,15 +27597,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NumberAtom = Number => ActionFn(1375); - let __sym0 = __pop_Variant81(__symbols); + // NumberAtom = Number => ActionFn(1377); + let __sym0 = __pop_Variant84(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1375::<>(source_code, mode, __sym0); + let __nt = super::__action1377::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 196) } - pub(crate) fn __reduce521< + pub(crate) fn __reduce522< >( source_code: &str, mode: Mode, @@ -27497,7 +27622,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 197) } - pub(crate) fn __reduce522< + pub(crate) fn __reduce523< >( source_code: &str, mode: Mode, @@ -27506,17 +27631,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NumberExpr = "-", NumberAtom => ActionFn(1376); + // NumberExpr = "-", NumberAtom => ActionFn(1378); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1376::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1378::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 197) } - pub(crate) fn __reduce523< + pub(crate) fn __reduce524< >( source_code: &str, mode: Mode, @@ -27525,15 +27650,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = DictElement => ActionFn(260); + // OneOrMore = DictElement => ActionFn(263); let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action260::<>(source_code, mode, __sym0); + let __nt = super::__action263::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant61(__nt), __end)); (1, 198) } - pub(crate) fn __reduce524< + pub(crate) fn __reduce525< >( source_code: &str, mode: Mode, @@ -27542,18 +27667,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", DictElement => ActionFn(261); + // OneOrMore = OneOrMore, ",", DictElement => ActionFn(264); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant59(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant61(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action261::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action264::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant61(__nt), __end)); (3, 198) } - pub(crate) fn __reduce525< + pub(crate) fn __reduce526< >( source_code: &str, mode: Mode, @@ -27562,15 +27687,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = ExpressionOrStarExpression => ActionFn(257); + // OneOrMore = ExpressionOrStarExpression => ActionFn(260); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action257::<>(source_code, mode, __sym0); + let __nt = super::__action260::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (1, 199) } - pub(crate) fn __reduce526< + pub(crate) fn __reduce527< >( source_code: &str, mode: Mode, @@ -27579,18 +27704,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", ExpressionOrStarExpression => ActionFn(258); + // OneOrMore = OneOrMore, ",", ExpressionOrStarExpression => ActionFn(261); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action258::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action261::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (3, 199) } - pub(crate) fn __reduce527< + pub(crate) fn __reduce528< >( source_code: &str, mode: Mode, @@ -27599,15 +27724,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = Identifier => ActionFn(376); + // OneOrMore = Identifier => ActionFn(379); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action376::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant82(__nt), __end)); + let __nt = super::__action379::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant85(__nt), __end)); (1, 200) } - pub(crate) fn __reduce528< + pub(crate) fn __reduce529< >( source_code: &str, mode: Mode, @@ -27616,18 +27741,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", Identifier => ActionFn(377); + // OneOrMore = OneOrMore, ",", Identifier => ActionFn(380); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action377::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant82(__nt), __end)); + let __nt = super::__action380::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant85(__nt), __end)); (3, 200) } - pub(crate) fn __reduce529< + pub(crate) fn __reduce530< >( source_code: &str, mode: Mode, @@ -27636,18 +27761,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = DottedName, "as", Identifier => ActionFn(1589); + // OneOrMore> = DottedName, "as", Identifier => ActionFn(1593); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1589::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1593::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (3, 201) } - pub(crate) fn __reduce530< + pub(crate) fn __reduce531< >( source_code: &str, mode: Mode, @@ -27656,15 +27781,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = DottedName => ActionFn(1590); + // OneOrMore> = DottedName => ActionFn(1594); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1590::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1594::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (1, 201) } - pub(crate) fn __reduce531< + pub(crate) fn __reduce532< >( source_code: &str, mode: Mode, @@ -27673,20 +27798,20 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", DottedName, "as", Identifier => ActionFn(1591); + // OneOrMore> = OneOrMore>, ",", DottedName, "as", Identifier => ActionFn(1595); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant73(__symbols); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1591::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1595::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (5, 201) } - pub(crate) fn __reduce532< + pub(crate) fn __reduce533< >( source_code: &str, mode: Mode, @@ -27695,18 +27820,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", DottedName => ActionFn(1592); + // OneOrMore> = OneOrMore>, ",", DottedName => ActionFn(1596); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant73(__symbols); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1592::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1596::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (3, 201) } - pub(crate) fn __reduce533< + pub(crate) fn __reduce534< >( source_code: &str, mode: Mode, @@ -27715,18 +27840,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = Identifier, "as", Identifier => ActionFn(1593); + // OneOrMore> = Identifier, "as", Identifier => ActionFn(1597); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1593::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1597::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (3, 202) } - pub(crate) fn __reduce534< + pub(crate) fn __reduce535< >( source_code: &str, mode: Mode, @@ -27735,15 +27860,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = Identifier => ActionFn(1594); + // OneOrMore> = Identifier => ActionFn(1598); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1594::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1598::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (1, 202) } - pub(crate) fn __reduce535< + pub(crate) fn __reduce536< >( source_code: &str, mode: Mode, @@ -27752,20 +27877,20 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", Identifier, "as", Identifier => ActionFn(1595); + // OneOrMore> = OneOrMore>, ",", Identifier, "as", Identifier => ActionFn(1599); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant73(__symbols); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1595::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1599::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (5, 202) } - pub(crate) fn __reduce536< + pub(crate) fn __reduce537< >( source_code: &str, mode: Mode, @@ -27774,18 +27899,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", Identifier => ActionFn(1596); + // OneOrMore> = OneOrMore>, ",", Identifier => ActionFn(1600); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant73(__symbols); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1596::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + let __nt = super::__action1600::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); (3, 202) } - pub(crate) fn __reduce537< + pub(crate) fn __reduce538< >( source_code: &str, mode: Mode, @@ -27794,15 +27919,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = MatchKeywordEntry => ActionFn(343); - let __sym0 = __pop_Variant79(__symbols); + // OneOrMore = MatchKeywordEntry => ActionFn(348); + let __sym0 = __pop_Variant82(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action343::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant83(__nt), __end)); + let __nt = super::__action348::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant86(__nt), __end)); (1, 203) } - pub(crate) fn __reduce538< + pub(crate) fn __reduce539< >( source_code: &str, mode: Mode, @@ -27811,18 +27936,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", MatchKeywordEntry => ActionFn(344); + // OneOrMore = OneOrMore, ",", MatchKeywordEntry => ActionFn(349); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant79(__symbols); + let __sym2 = __pop_Variant82(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant83(__symbols); + let __sym0 = __pop_Variant86(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action344::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant83(__nt), __end)); + let __nt = super::__action349::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant86(__nt), __end)); (3, 203) } - pub(crate) fn __reduce539< + pub(crate) fn __reduce540< >( source_code: &str, mode: Mode, @@ -27831,15 +27956,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = MatchMappingEntry => ActionFn(347); - let __sym0 = __pop_Variant80(__symbols); + // OneOrMore = MatchMappingEntry => ActionFn(352); + let __sym0 = __pop_Variant83(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action347::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant84(__nt), __end)); + let __nt = super::__action352::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant87(__nt), __end)); (1, 204) } - pub(crate) fn __reduce540< + pub(crate) fn __reduce541< >( source_code: &str, mode: Mode, @@ -27848,18 +27973,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", MatchMappingEntry => ActionFn(348); + // OneOrMore = OneOrMore, ",", MatchMappingEntry => ActionFn(353); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant80(__symbols); + let __sym2 = __pop_Variant83(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant84(__symbols); + let __sym0 = __pop_Variant87(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action348::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant84(__nt), __end)); + let __nt = super::__action353::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant87(__nt), __end)); (3, 204) } - pub(crate) fn __reduce541< + pub(crate) fn __reduce542< >( source_code: &str, mode: Mode, @@ -27868,15 +27993,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = ParameterDef => ActionFn(487); + // OneOrMore> = ParameterDef => ActionFn(490); let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action487::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant85(__nt), __end)); + let __nt = super::__action490::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant88(__nt), __end)); (1, 205) } - pub(crate) fn __reduce542< + pub(crate) fn __reduce543< >( source_code: &str, mode: Mode, @@ -27885,18 +28010,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", ParameterDef => ActionFn(488); + // OneOrMore> = OneOrMore>, ",", ParameterDef => ActionFn(491); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant11(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action488::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant85(__nt), __end)); + let __nt = super::__action491::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant88(__nt), __end)); (3, 205) } - pub(crate) fn __reduce543< + pub(crate) fn __reduce544< >( source_code: &str, mode: Mode, @@ -27905,15 +28030,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = ParameterDef => ActionFn(476); + // OneOrMore> = ParameterDef => ActionFn(479); let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action476::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant85(__nt), __end)); + let __nt = super::__action479::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant88(__nt), __end)); (1, 206) } - pub(crate) fn __reduce544< + pub(crate) fn __reduce545< >( source_code: &str, mode: Mode, @@ -27922,18 +28047,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", ParameterDef => ActionFn(477); + // OneOrMore> = OneOrMore>, ",", ParameterDef => ActionFn(480); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant11(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action477::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant85(__nt), __end)); + let __nt = super::__action480::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant88(__nt), __end)); (3, 206) } - pub(crate) fn __reduce545< + pub(crate) fn __reduce546< >( source_code: &str, mode: Mode, @@ -27942,15 +28067,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = Pattern => ActionFn(345); + // OneOrMore = Pattern => ActionFn(350); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action345::<>(source_code, mode, __sym0); + let __nt = super::__action350::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); (1, 207) } - pub(crate) fn __reduce546< + pub(crate) fn __reduce547< >( source_code: &str, mode: Mode, @@ -27959,18 +28084,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", Pattern => ActionFn(346); + // OneOrMore = OneOrMore, ",", Pattern => ActionFn(351); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action346::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action351::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); (3, 207) } - pub(crate) fn __reduce547< + pub(crate) fn __reduce548< >( source_code: &str, mode: Mode, @@ -27979,15 +28104,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = Test<"all"> => ActionFn(308); + // OneOrMore> = Test<"all"> => ActionFn(313); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action308::<>(source_code, mode, __sym0); + let __nt = super::__action313::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (1, 208) } - pub(crate) fn __reduce548< + pub(crate) fn __reduce549< >( source_code: &str, mode: Mode, @@ -27996,18 +28121,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", Test<"all"> => ActionFn(309); + // OneOrMore> = OneOrMore>, ",", Test<"all"> => ActionFn(314); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action309::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action314::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (3, 208) } - pub(crate) fn __reduce549< + pub(crate) fn __reduce550< >( source_code: &str, mode: Mode, @@ -28016,15 +28141,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = TestOrStarExpr => ActionFn(455); + // OneOrMore = TestOrStarExpr => ActionFn(458); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action455::<>(source_code, mode, __sym0); + let __nt = super::__action458::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (1, 209) } - pub(crate) fn __reduce550< + pub(crate) fn __reduce551< >( source_code: &str, mode: Mode, @@ -28033,18 +28158,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", TestOrStarExpr => ActionFn(456); + // OneOrMore = OneOrMore, ",", TestOrStarExpr => ActionFn(459); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action456::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action459::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (3, 209) } - pub(crate) fn __reduce551< + pub(crate) fn __reduce552< >( source_code: &str, mode: Mode, @@ -28053,15 +28178,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = TestOrStarNamedExpr => ActionFn(262); + // OneOrMore = TestOrStarNamedExpr => ActionFn(265); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action262::<>(source_code, mode, __sym0); + let __nt = super::__action265::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (1, 210) } - pub(crate) fn __reduce552< + pub(crate) fn __reduce553< >( source_code: &str, mode: Mode, @@ -28070,18 +28195,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", TestOrStarNamedExpr => ActionFn(263); + // OneOrMore = OneOrMore, ",", TestOrStarNamedExpr => ActionFn(266); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action263::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action266::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (3, 210) } - pub(crate) fn __reduce553< + pub(crate) fn __reduce554< >( source_code: &str, mode: Mode, @@ -28090,15 +28215,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = TypeParam => ActionFn(284); - let __sym0 = __pop_Variant97(__symbols); + // OneOrMore = TypeParam => ActionFn(289); + let __sym0 = __pop_Variant100(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action284::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); + let __nt = super::__action289::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); (1, 211) } - pub(crate) fn __reduce554< + pub(crate) fn __reduce555< >( source_code: &str, mode: Mode, @@ -28107,18 +28232,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", TypeParam => ActionFn(285); + // OneOrMore = OneOrMore, ",", TypeParam => ActionFn(290); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant97(__symbols); + let __sym2 = __pop_Variant100(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant86(__symbols); + let __sym0 = __pop_Variant89(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action285::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); + let __nt = super::__action290::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); (3, 211) } - pub(crate) fn __reduce555< + pub(crate) fn __reduce556< >( source_code: &str, mode: Mode, @@ -28135,7 +28260,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 212) } - pub(crate) fn __reduce556< + pub(crate) fn __reduce557< >( source_code: &str, mode: Mode, @@ -28144,15 +28269,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrPattern = TwoOrMore => ActionFn(1377); + // OrPattern = TwoOrMoreSep => ActionFn(1379); let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1377::<>(source_code, mode, __sym0); + let __nt = super::__action1379::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 212) } - pub(crate) fn __reduce557< + pub(crate) fn __reduce558< >( source_code: &str, mode: Mode, @@ -28161,17 +28286,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrTest<"all"> = (> "or")+, AndTest<"all"> => ActionFn(1378); + // OrTest<"all"> = (> "or")+, AndTest<"all"> => ActionFn(1380); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1378::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1380::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 213) } - pub(crate) fn __reduce558< + pub(crate) fn __reduce559< >( source_code: &str, mode: Mode, @@ -28180,15 +28305,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrTest<"all"> = AndTest<"all"> => ActionFn(253); + // OrTest<"all"> = AndTest<"all"> => ActionFn(256); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action253::<>(source_code, mode, __sym0); + let __nt = super::__action256::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 213) } - pub(crate) fn __reduce559< + pub(crate) fn __reduce560< >( source_code: &str, mode: Mode, @@ -28197,17 +28322,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrTest<"no-withitems"> = (> "or")+, AndTest<"all"> => ActionFn(1379); + // OrTest<"no-withitems"> = (> "or")+, AndTest<"all"> => ActionFn(1381); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1379::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1381::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 214) } - pub(crate) fn __reduce560< + pub(crate) fn __reduce561< >( source_code: &str, mode: Mode, @@ -28216,15 +28341,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrTest<"no-withitems"> = AndTest<"no-withitems"> => ActionFn(501); + // OrTest<"no-withitems"> = AndTest<"no-withitems"> => ActionFn(504); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action501::<>(source_code, mode, __sym0); + let __nt = super::__action504::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 214) } - pub(crate) fn __reduce561< + pub(crate) fn __reduce562< >( source_code: &str, mode: Mode, @@ -28233,15 +28358,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDef = TypedParameter => ActionFn(494); + // ParameterDef = TypedParameter => ActionFn(497); let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action494::<>(source_code, mode, __sym0); + let __nt = super::__action497::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); (1, 215) } - pub(crate) fn __reduce562< + pub(crate) fn __reduce563< >( source_code: &str, mode: Mode, @@ -28250,18 +28375,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDef = TypedParameter, "=", Test<"all"> => ActionFn(1380); + // ParameterDef = TypedParameter, "=", Test<"all"> => ActionFn(1382); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1380::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1382::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); (3, 215) } - pub(crate) fn __reduce563< + pub(crate) fn __reduce564< >( source_code: &str, mode: Mode, @@ -28270,15 +28395,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDef = UntypedParameter => ActionFn(483); + // ParameterDef = UntypedParameter => ActionFn(486); let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action483::<>(source_code, mode, __sym0); + let __nt = super::__action486::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); (1, 216) } - pub(crate) fn __reduce564< + pub(crate) fn __reduce565< >( source_code: &str, mode: Mode, @@ -28287,18 +28412,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDef = UntypedParameter, "=", Test<"all"> => ActionFn(1381); + // ParameterDef = UntypedParameter, "=", Test<"all"> => ActionFn(1383); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1381::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1383::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); (3, 216) } - pub(crate) fn __reduce565< + pub(crate) fn __reduce566< >( source_code: &str, mode: Mode, @@ -28307,15 +28432,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore> => ActionFn(443); - let __sym0 = __pop_Variant85(__symbols); + // ParameterDefs = OneOrMore> => ActionFn(446); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action443::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + let __nt = super::__action446::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); (1, 217) } - pub(crate) fn __reduce566< + pub(crate) fn __reduce567< >( source_code: &str, mode: Mode, @@ -28324,18 +28449,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore>, ",", "/" => ActionFn(698); + // ParameterDefs = OneOrMore>, ",", "/" => ActionFn(701); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action698::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + let __nt = super::__action701::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); (3, 217) } - pub(crate) fn __reduce567< + pub(crate) fn __reduce568< >( source_code: &str, mode: Mode, @@ -28344,19 +28469,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore>, ",", "/", ("," >)+ => ActionFn(699); + // ParameterDefs = OneOrMore>, ",", "/", ("," >)+ => ActionFn(702); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action699::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + let __nt = super::__action702::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); (4, 217) } - pub(crate) fn __reduce568< + pub(crate) fn __reduce569< >( source_code: &str, mode: Mode, @@ -28365,15 +28490,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore> => ActionFn(451); - let __sym0 = __pop_Variant85(__symbols); + // ParameterDefs = OneOrMore> => ActionFn(454); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action451::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + let __nt = super::__action454::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); (1, 218) } - pub(crate) fn __reduce569< + pub(crate) fn __reduce570< >( source_code: &str, mode: Mode, @@ -28382,18 +28507,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore>, ",", "/" => ActionFn(706); + // ParameterDefs = OneOrMore>, ",", "/" => ActionFn(709); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action706::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + let __nt = super::__action709::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); (3, 218) } - pub(crate) fn __reduce570< + pub(crate) fn __reduce571< >( source_code: &str, mode: Mode, @@ -28402,19 +28527,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore>, ",", "/", ("," >)+ => ActionFn(707); + // ParameterDefs = OneOrMore>, ",", "/", ("," >)+ => ActionFn(710); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant85(__symbols); + let __sym0 = __pop_Variant88(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action707::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + let __nt = super::__action710::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); (4, 218) } - pub(crate) fn __reduce647< + pub(crate) fn __reduce648< >( source_code: &str, mode: Mode, @@ -28423,17 +28548,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList = KwargParameter, "," => ActionFn(1418); + // ParameterList = KwargParameter, "," => ActionFn(1420); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1418::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1420::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 219) } - pub(crate) fn __reduce648< + pub(crate) fn __reduce649< >( source_code: &str, mode: Mode, @@ -28442,15 +28567,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList = KwargParameter => ActionFn(1419); + // ParameterList = KwargParameter => ActionFn(1421); let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1419::<>(source_code, mode, __sym0); + let __nt = super::__action1421::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (1, 219) } - pub(crate) fn __reduce725< + pub(crate) fn __reduce726< >( source_code: &str, mode: Mode, @@ -28459,17 +28584,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList = KwargParameter, "," => ActionFn(1456); + // ParameterList = KwargParameter, "," => ActionFn(1458); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1456::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1458::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (2, 220) } - pub(crate) fn __reduce726< + pub(crate) fn __reduce727< >( source_code: &str, mode: Mode, @@ -28478,15 +28603,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList = KwargParameter => ActionFn(1457); + // ParameterList = KwargParameter => ActionFn(1459); let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1457::<>(source_code, mode, __sym0); + let __nt = super::__action1459::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant46(__nt), __end)); (1, 220) } - pub(crate) fn __reduce727< + pub(crate) fn __reduce728< >( source_code: &str, mode: Mode, @@ -28495,15 +28620,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList? = ParameterList => ActionFn(278); + // ParameterList? = ParameterList => ActionFn(283); let __sym0 = __pop_Variant46(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action278::<>(source_code, mode, __sym0); + let __nt = super::__action283::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant47(__nt), __end)); (1, 221) } - pub(crate) fn __reduce728< + pub(crate) fn __reduce729< >( source_code: &str, mode: Mode, @@ -28512,14 +28637,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList? = => ActionFn(279); + // ParameterList? = => ActionFn(284); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action279::<>(source_code, mode, &__start, &__end); + let __nt = super::__action284::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant47(__nt), __end)); (0, 221) } - pub(crate) fn __reduce747< + pub(crate) fn __reduce748< >( source_code: &str, mode: Mode, @@ -28528,15 +28653,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PassStatement = "pass" => ActionFn(1460); + // PassStatement = "pass" => ActionFn(1462); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1460::<>(source_code, mode, __sym0); + let __nt = super::__action1462::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 225) } - pub(crate) fn __reduce748< + pub(crate) fn __reduce749< >( source_code: &str, mode: Mode, @@ -28553,7 +28678,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 226) } - pub(crate) fn __reduce749< + pub(crate) fn __reduce750< >( source_code: &str, mode: Mode, @@ -28570,7 +28695,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 226) } - pub(crate) fn __reduce750< + pub(crate) fn __reduce751< >( source_code: &str, mode: Mode, @@ -28579,15 +28704,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Pattern? = Pattern => ActionFn(426); + // Pattern? = Pattern => ActionFn(429); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action426::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant88(__nt), __end)); + let __nt = super::__action429::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant91(__nt), __end)); (1, 227) } - pub(crate) fn __reduce751< + pub(crate) fn __reduce752< >( source_code: &str, mode: Mode, @@ -28596,14 +28721,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Pattern? = => ActionFn(427); + // Pattern? = => ActionFn(430); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action427::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant88(__nt), __end)); + let __nt = super::__action430::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant91(__nt), __end)); (0, 227) } - pub(crate) fn __reduce752< + pub(crate) fn __reduce753< >( source_code: &str, mode: Mode, @@ -28612,21 +28737,21 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ",", OneOrMore, ",", ")" => ActionFn(1461); + // PatternArguments = "(", OneOrMore, ",", OneOrMore, ",", ")" => ActionFn(1463); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant83(__symbols); + let __sym3 = __pop_Variant86(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant53(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1461::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + let __nt = super::__action1463::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); (6, 228) } - pub(crate) fn __reduce753< + pub(crate) fn __reduce754< >( source_code: &str, mode: Mode, @@ -28635,20 +28760,20 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ",", OneOrMore, ")" => ActionFn(1462); + // PatternArguments = "(", OneOrMore, ",", OneOrMore, ")" => ActionFn(1464); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant83(__symbols); + let __sym3 = __pop_Variant86(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant53(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1462::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + let __nt = super::__action1464::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); (5, 228) } - pub(crate) fn __reduce754< + pub(crate) fn __reduce755< >( source_code: &str, mode: Mode, @@ -28657,7 +28782,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ",", ")" => ActionFn(1463); + // PatternArguments = "(", OneOrMore, ",", ")" => ActionFn(1465); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -28665,11 +28790,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1463::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + let __nt = super::__action1465::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); (4, 228) } - pub(crate) fn __reduce755< + pub(crate) fn __reduce756< >( source_code: &str, mode: Mode, @@ -28678,18 +28803,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ")" => ActionFn(1464); + // PatternArguments = "(", OneOrMore, ")" => ActionFn(1466); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant53(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1464::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + let __nt = super::__action1466::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); (3, 228) } - pub(crate) fn __reduce756< + pub(crate) fn __reduce757< >( source_code: &str, mode: Mode, @@ -28698,19 +28823,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ",", ")" => ActionFn(1465); + // PatternArguments = "(", OneOrMore, ",", ")" => ActionFn(1467); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant83(__symbols); + let __sym1 = __pop_Variant86(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1465::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + let __nt = super::__action1467::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); (4, 228) } - pub(crate) fn __reduce757< + pub(crate) fn __reduce758< >( source_code: &str, mode: Mode, @@ -28719,18 +28844,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ")" => ActionFn(1466); + // PatternArguments = "(", OneOrMore, ")" => ActionFn(1468); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant83(__symbols); + let __sym1 = __pop_Variant86(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1466::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + let __nt = super::__action1468::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); (3, 228) } - pub(crate) fn __reduce758< + pub(crate) fn __reduce759< >( source_code: &str, mode: Mode, @@ -28739,17 +28864,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", ")" => ActionFn(1467); + // PatternArguments = "(", ")" => ActionFn(1469); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1467::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + let __nt = super::__action1469::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); (2, 228) } - pub(crate) fn __reduce759< + pub(crate) fn __reduce760< >( source_code: &str, mode: Mode, @@ -28758,17 +28883,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Patterns = Pattern, "," => ActionFn(1468); + // Patterns = Pattern, "," => ActionFn(1470); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1468::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1470::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 229) } - pub(crate) fn __reduce760< + pub(crate) fn __reduce761< >( source_code: &str, mode: Mode, @@ -28777,17 +28902,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Patterns = TwoOrMore, "," => ActionFn(1469); + // Patterns = TwoOrMoreSep, "," => ActionFn(1471); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1469::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1471::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 229) } - pub(crate) fn __reduce761< + pub(crate) fn __reduce762< >( source_code: &str, mode: Mode, @@ -28796,15 +28921,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Patterns = TwoOrMore => ActionFn(1470); + // Patterns = TwoOrMoreSep => ActionFn(1472); let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1470::<>(source_code, mode, __sym0); + let __nt = super::__action1472::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 229) } - pub(crate) fn __reduce762< + pub(crate) fn __reduce763< >( source_code: &str, mode: Mode, @@ -28821,7 +28946,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (1, 229) } - pub(crate) fn __reduce763< + pub(crate) fn __reduce764< >( source_code: &str, mode: Mode, @@ -28830,18 +28955,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Power<"all"> = AtomExpr<"all">, "**", Factor<"all"> => ActionFn(1471); + // Power<"all"> = AtomExpr<"all">, "**", Factor<"all"> => ActionFn(1473); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1471::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1473::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 230) } - pub(crate) fn __reduce764< + pub(crate) fn __reduce765< >( source_code: &str, mode: Mode, @@ -28850,15 +28975,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Power<"all"> = AtomExpr<"all"> => ActionFn(530); + // Power<"all"> = AtomExpr<"all"> => ActionFn(533); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action530::<>(source_code, mode, __sym0); + let __nt = super::__action533::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 230) } - pub(crate) fn __reduce765< + pub(crate) fn __reduce766< >( source_code: &str, mode: Mode, @@ -28867,18 +28992,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Power<"no-withitems"> = AtomExpr<"all">, "**", Factor<"all"> => ActionFn(1472); + // Power<"no-withitems"> = AtomExpr<"all">, "**", Factor<"all"> => ActionFn(1474); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1472::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1474::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 231) } - pub(crate) fn __reduce766< + pub(crate) fn __reduce767< >( source_code: &str, mode: Mode, @@ -28887,15 +29012,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Power<"no-withitems"> = AtomExpr<"no-withitems"> => ActionFn(581); + // Power<"no-withitems"> = AtomExpr<"no-withitems"> => ActionFn(584); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action581::<>(source_code, mode, __sym0); + let __nt = super::__action584::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 231) } - pub(crate) fn __reduce767< + pub(crate) fn __reduce768< >( source_code: &str, mode: Mode, @@ -28911,7 +29036,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (0, 232) } - pub(crate) fn __reduce768< + pub(crate) fn __reduce769< >( source_code: &str, mode: Mode, @@ -28930,7 +29055,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (2, 232) } - pub(crate) fn __reduce769< + pub(crate) fn __reduce770< >( source_code: &str, mode: Mode, @@ -28939,7 +29064,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Program = Program, SmallStatement, ";", "\n" => ActionFn(1187); + // Program = Program, SmallStatement, ";", "\n" => ActionFn(1190); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -28947,11 +29072,11 @@ mod __parse__Top { let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1187::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1190::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (4, 232) } - pub(crate) fn __reduce770< + pub(crate) fn __reduce771< >( source_code: &str, mode: Mode, @@ -28960,7 +29085,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Program = Program, ( ";")+, SmallStatement, ";", "\n" => ActionFn(1188); + // Program = Program, ( ";")+, SmallStatement, ";", "\n" => ActionFn(1191); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -28969,11 +29094,11 @@ mod __parse__Top { let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1188::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1191::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (5, 232) } - pub(crate) fn __reduce771< + pub(crate) fn __reduce772< >( source_code: &str, mode: Mode, @@ -28982,18 +29107,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Program = Program, SmallStatement, "\n" => ActionFn(1189); + // Program = Program, SmallStatement, "\n" => ActionFn(1192); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant37(__symbols); let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1189::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1192::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (3, 232) } - pub(crate) fn __reduce772< + pub(crate) fn __reduce773< >( source_code: &str, mode: Mode, @@ -29002,7 +29127,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Program = Program, ( ";")+, SmallStatement, "\n" => ActionFn(1190); + // Program = Program, ( ";")+, SmallStatement, "\n" => ActionFn(1193); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant37(__symbols); @@ -29010,11 +29135,11 @@ mod __parse__Top { let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1190::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1193::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (4, 232) } - pub(crate) fn __reduce773< + pub(crate) fn __reduce774< >( source_code: &str, mode: Mode, @@ -29033,7 +29158,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant25(__nt), __end)); (2, 232) } - pub(crate) fn __reduce774< + pub(crate) fn __reduce775< >( source_code: &str, mode: Mode, @@ -29042,15 +29167,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // RaiseStatement = "raise" => ActionFn(1473); + // RaiseStatement = "raise" => ActionFn(1475); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1473::<>(source_code, mode, __sym0); + let __nt = super::__action1475::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 233) } - pub(crate) fn __reduce775< + pub(crate) fn __reduce776< >( source_code: &str, mode: Mode, @@ -29059,7 +29184,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // RaiseStatement = "raise", Test<"all">, "from", Test<"all"> => ActionFn(1474); + // RaiseStatement = "raise", Test<"all">, "from", Test<"all"> => ActionFn(1476); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -29067,11 +29192,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1474::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1476::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (4, 233) } - pub(crate) fn __reduce776< + pub(crate) fn __reduce777< >( source_code: &str, mode: Mode, @@ -29080,17 +29205,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // RaiseStatement = "raise", Test<"all"> => ActionFn(1475); + // RaiseStatement = "raise", Test<"all"> => ActionFn(1477); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1475::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1477::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (2, 233) } - pub(crate) fn __reduce777< + pub(crate) fn __reduce778< >( source_code: &str, mode: Mode, @@ -29099,18 +29224,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", Pattern, ")" => ActionFn(1476); + // SequencePattern = "(", Pattern, ")" => ActionFn(1478); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1476::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1478::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (3, 234) } - pub(crate) fn __reduce778< + pub(crate) fn __reduce779< >( source_code: &str, mode: Mode, @@ -29119,17 +29244,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", ")" => ActionFn(1477); + // SequencePattern = "(", ")" => ActionFn(1479); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1477::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1479::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 234) } - pub(crate) fn __reduce779< + pub(crate) fn __reduce780< >( source_code: &str, mode: Mode, @@ -29138,7 +29263,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", Pattern, ",", ")" => ActionFn(1478); + // SequencePattern = "(", Pattern, ",", ")" => ActionFn(1480); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -29146,11 +29271,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1478::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1480::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (4, 234) } - pub(crate) fn __reduce780< + pub(crate) fn __reduce781< >( source_code: &str, mode: Mode, @@ -29159,7 +29284,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", ( ",")+, Pattern, ",", ")" => ActionFn(1479); + // SequencePattern = "(", ( ",")+, Pattern, ",", ")" => ActionFn(1481); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -29168,11 +29293,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1479::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1481::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (5, 234) } - pub(crate) fn __reduce781< + pub(crate) fn __reduce782< >( source_code: &str, mode: Mode, @@ -29181,7 +29306,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", ( ",")+, Pattern, ")" => ActionFn(1480); + // SequencePattern = "(", ( ",")+, Pattern, ")" => ActionFn(1482); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant35(__symbols); @@ -29189,11 +29314,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1480::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1482::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (4, 234) } - pub(crate) fn __reduce782< + pub(crate) fn __reduce783< >( source_code: &str, mode: Mode, @@ -29202,18 +29327,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "[", Pattern, "]" => ActionFn(1545); + // SequencePattern = "[", Pattern, "]" => ActionFn(1549); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1545::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1549::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (3, 234) } - pub(crate) fn __reduce783< + pub(crate) fn __reduce784< >( source_code: &str, mode: Mode, @@ -29222,17 +29347,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "[", "]" => ActionFn(1546); + // SequencePattern = "[", "]" => ActionFn(1550); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1546::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1550::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 234) } - pub(crate) fn __reduce784< + pub(crate) fn __reduce785< >( source_code: &str, mode: Mode, @@ -29241,7 +29366,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "[", ( ",")+, Pattern, "]" => ActionFn(1547); + // SequencePattern = "[", ( ",")+, Pattern, "]" => ActionFn(1551); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant35(__symbols); @@ -29249,11 +29374,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1547::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1551::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (4, 234) } - pub(crate) fn __reduce785< + pub(crate) fn __reduce786< >( source_code: &str, mode: Mode, @@ -29262,18 +29387,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "[", ( ",")+, "]" => ActionFn(1548); + // SequencePattern = "[", ( ",")+, "]" => ActionFn(1552); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant36(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1548::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1552::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (3, 234) } - pub(crate) fn __reduce786< + pub(crate) fn __reduce787< >( source_code: &str, mode: Mode, @@ -29282,17 +29407,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SetLiteralValues = OneOrMore, "," => ActionFn(658); + // SetLiteralValues = OneOrMore, "," => ActionFn(661); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action658::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action661::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (2, 235) } - pub(crate) fn __reduce787< + pub(crate) fn __reduce788< >( source_code: &str, mode: Mode, @@ -29301,15 +29426,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SetLiteralValues = OneOrMore => ActionFn(659); + // SetLiteralValues = OneOrMore => ActionFn(662); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action659::<>(source_code, mode, __sym0); + let __nt = super::__action662::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); (1, 235) } - pub(crate) fn __reduce788< + pub(crate) fn __reduce789< >( source_code: &str, mode: Mode, @@ -29318,18 +29443,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftExpression<"all"> = ShiftExpression<"all">, ShiftOp, ArithmeticExpression<"all"> => ActionFn(1482); + // ShiftExpression<"all"> = ShiftExpression<"all">, ShiftOp, ArithmeticExpression<"all"> => ActionFn(1484); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant49(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1482::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1484::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 236) } - pub(crate) fn __reduce789< + pub(crate) fn __reduce790< >( source_code: &str, mode: Mode, @@ -29338,15 +29463,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftExpression<"all"> = ArithmeticExpression<"all"> => ActionFn(505); + // ShiftExpression<"all"> = ArithmeticExpression<"all"> => ActionFn(508); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action505::<>(source_code, mode, __sym0); + let __nt = super::__action508::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 236) } - pub(crate) fn __reduce790< + pub(crate) fn __reduce791< >( source_code: &str, mode: Mode, @@ -29355,18 +29480,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftExpression<"no-withitems"> = ShiftExpression<"all">, ShiftOp, ArithmeticExpression<"all"> => ActionFn(1483); + // ShiftExpression<"no-withitems"> = ShiftExpression<"all">, ShiftOp, ArithmeticExpression<"all"> => ActionFn(1485); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant49(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1483::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1485::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (3, 237) } - pub(crate) fn __reduce791< + pub(crate) fn __reduce792< >( source_code: &str, mode: Mode, @@ -29375,15 +29500,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftExpression<"no-withitems"> = ArithmeticExpression<"no-withitems"> => ActionFn(542); + // ShiftExpression<"no-withitems"> = ArithmeticExpression<"no-withitems"> => ActionFn(545); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action542::<>(source_code, mode, __sym0); + let __nt = super::__action545::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 237) } - pub(crate) fn __reduce792< + pub(crate) fn __reduce793< >( source_code: &str, mode: Mode, @@ -29392,15 +29517,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftOp = "<<" => ActionFn(194); + // ShiftOp = "<<" => ActionFn(195); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action194::<>(source_code, mode, __sym0); + let __nt = super::__action195::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 238) } - pub(crate) fn __reduce793< + pub(crate) fn __reduce794< >( source_code: &str, mode: Mode, @@ -29409,15 +29534,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftOp = ">>" => ActionFn(195); + // ShiftOp = ">>" => ActionFn(196); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action195::<>(source_code, mode, __sym0); + let __nt = super::__action196::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant49(__nt), __end)); (1, 238) } - pub(crate) fn __reduce794< + pub(crate) fn __reduce795< >( source_code: &str, mode: Mode, @@ -29426,7 +29551,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension = "async", "for", ExpressionList, "in", OrTest<"all"> => ActionFn(1551); + // SingleForComprehension = "async", "for", ExpressionList, "in", OrTest<"all"> => ActionFn(1555); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -29435,11 +29560,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1551::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant90(__nt), __end)); + let __nt = super::__action1555::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant93(__nt), __end)); (5, 239) } - pub(crate) fn __reduce795< + pub(crate) fn __reduce796< >( source_code: &str, mode: Mode, @@ -29448,7 +29573,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension = "async", "for", ExpressionList, "in", OrTest<"all">, ComprehensionIf+ => ActionFn(1552); + // SingleForComprehension = "async", "for", ExpressionList, "in", OrTest<"all">, ComprehensionIf+ => ActionFn(1556); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant17(__symbols); let __sym4 = __pop_Variant15(__symbols); @@ -29458,11 +29583,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1552::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant90(__nt), __end)); + let __nt = super::__action1556::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant93(__nt), __end)); (6, 239) } - pub(crate) fn __reduce796< + pub(crate) fn __reduce797< >( source_code: &str, mode: Mode, @@ -29471,7 +29596,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension = "for", ExpressionList, "in", OrTest<"all"> => ActionFn(1553); + // SingleForComprehension = "for", ExpressionList, "in", OrTest<"all"> => ActionFn(1557); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -29479,11 +29604,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1553::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant90(__nt), __end)); + let __nt = super::__action1557::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant93(__nt), __end)); (4, 239) } - pub(crate) fn __reduce797< + pub(crate) fn __reduce798< >( source_code: &str, mode: Mode, @@ -29492,7 +29617,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension = "for", ExpressionList, "in", OrTest<"all">, ComprehensionIf+ => ActionFn(1554); + // SingleForComprehension = "for", ExpressionList, "in", OrTest<"all">, ComprehensionIf+ => ActionFn(1558); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant17(__symbols); let __sym3 = __pop_Variant15(__symbols); @@ -29501,11 +29626,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1554::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant90(__nt), __end)); + let __nt = super::__action1558::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant93(__nt), __end)); (5, 239) } - pub(crate) fn __reduce798< + pub(crate) fn __reduce799< >( source_code: &str, mode: Mode, @@ -29514,15 +29639,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension+ = SingleForComprehension => ActionFn(254); - let __sym0 = __pop_Variant90(__symbols); + // SingleForComprehension+ = SingleForComprehension => ActionFn(257); + let __sym0 = __pop_Variant93(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action254::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); + let __nt = super::__action257::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); (1, 240) } - pub(crate) fn __reduce799< + pub(crate) fn __reduce800< >( source_code: &str, mode: Mode, @@ -29531,17 +29656,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension+ = SingleForComprehension+, SingleForComprehension => ActionFn(255); + // SingleForComprehension+ = SingleForComprehension+, SingleForComprehension => ActionFn(258); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant90(__symbols); - let __sym0 = __pop_Variant91(__symbols); + let __sym1 = __pop_Variant93(__symbols); + let __sym0 = __pop_Variant94(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action255::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); + let __nt = super::__action258::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); (2, 240) } - pub(crate) fn __reduce800< + pub(crate) fn __reduce801< >( source_code: &str, mode: Mode, @@ -29550,17 +29675,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SliceOp = ":", Test<"all"> => ActionFn(1729); + // SliceOp = ":", Test<"all"> => ActionFn(1733); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1729::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant92(__nt), __end)); + let __nt = super::__action1733::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant95(__nt), __end)); (2, 241) } - pub(crate) fn __reduce801< + pub(crate) fn __reduce802< >( source_code: &str, mode: Mode, @@ -29569,15 +29694,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SliceOp = ":" => ActionFn(1730); + // SliceOp = ":" => ActionFn(1734); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1730::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant92(__nt), __end)); + let __nt = super::__action1734::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant95(__nt), __end)); (1, 241) } - pub(crate) fn __reduce802< + pub(crate) fn __reduce803< >( source_code: &str, mode: Mode, @@ -29586,15 +29711,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SliceOp? = SliceOp => ActionFn(272); - let __sym0 = __pop_Variant92(__symbols); + // SliceOp? = SliceOp => ActionFn(277); + let __sym0 = __pop_Variant95(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action272::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant93(__nt), __end)); + let __nt = super::__action277::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant96(__nt), __end)); (1, 242) } - pub(crate) fn __reduce803< + pub(crate) fn __reduce804< >( source_code: &str, mode: Mode, @@ -29603,14 +29728,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SliceOp? = => ActionFn(273); + // SliceOp? = => ActionFn(278); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action273::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant93(__nt), __end)); + let __nt = super::__action278::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant96(__nt), __end)); (0, 242) } - pub(crate) fn __reduce804< + pub(crate) fn __reduce805< >( source_code: &str, mode: Mode, @@ -29627,7 +29752,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce805< + pub(crate) fn __reduce806< >( source_code: &str, mode: Mode, @@ -29644,7 +29769,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce806< + pub(crate) fn __reduce807< >( source_code: &str, mode: Mode, @@ -29661,7 +29786,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce807< + pub(crate) fn __reduce808< >( source_code: &str, mode: Mode, @@ -29678,7 +29803,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce808< + pub(crate) fn __reduce809< >( source_code: &str, mode: Mode, @@ -29695,7 +29820,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce809< + pub(crate) fn __reduce810< >( source_code: &str, mode: Mode, @@ -29712,7 +29837,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce810< + pub(crate) fn __reduce811< >( source_code: &str, mode: Mode, @@ -29729,7 +29854,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce811< + pub(crate) fn __reduce812< >( source_code: &str, mode: Mode, @@ -29746,7 +29871,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce812< + pub(crate) fn __reduce813< >( source_code: &str, mode: Mode, @@ -29763,7 +29888,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce813< + pub(crate) fn __reduce814< >( source_code: &str, mode: Mode, @@ -29780,7 +29905,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce814< + pub(crate) fn __reduce815< >( source_code: &str, mode: Mode, @@ -29797,7 +29922,7 @@ mod __parse__Top { __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 243) } - pub(crate) fn __reduce815< + pub(crate) fn __reduce816< >( source_code: &str, mode: Mode, @@ -29806,17 +29931,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarExpr = "*", Expression<"all"> => ActionFn(1486); + // StarExpr = "*", Expression<"all"> => ActionFn(1488); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1486::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1488::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (2, 244) } - pub(crate) fn __reduce816< + pub(crate) fn __reduce817< >( source_code: &str, mode: Mode, @@ -29825,17 +29950,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarPattern = "*", Identifier => ActionFn(1487); + // StarPattern = "*", Identifier => ActionFn(1489); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1487::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1489::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); (2, 245) } - pub(crate) fn __reduce817< + pub(crate) fn __reduce818< >( source_code: &str, mode: Mode, @@ -29844,18 +29969,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarTypedParameter = Identifier, ":", TestOrStarExpr => ActionFn(1488); + // StarTypedParameter = Identifier, ":", TestOrStarExpr => ActionFn(1490); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1488::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1490::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant63(__nt), __end)); (3, 246) } - pub(crate) fn __reduce818< + pub(crate) fn __reduce819< >( source_code: &str, mode: Mode, @@ -29864,15 +29989,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarTypedParameter = Identifier => ActionFn(1489); + // StarTypedParameter = Identifier => ActionFn(1491); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1489::<>(source_code, mode, __sym0); + let __nt = super::__action1491::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant63(__nt), __end)); (1, 246) } - pub(crate) fn __reduce819< + pub(crate) fn __reduce820< >( source_code: &str, mode: Mode, @@ -29881,15 +30006,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarTypedParameter? = StarTypedParameter => ActionFn(496); + // StarTypedParameter? = StarTypedParameter => ActionFn(499); let __sym0 = __pop_Variant63(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action496::<>(source_code, mode, __sym0); + let __nt = super::__action499::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant64(__nt), __end)); (1, 247) } - pub(crate) fn __reduce820< + pub(crate) fn __reduce821< >( source_code: &str, mode: Mode, @@ -29898,14 +30023,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarTypedParameter? = => ActionFn(497); + // StarTypedParameter? = => ActionFn(500); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action497::<>(source_code, mode, &__start, &__end); + let __nt = super::__action500::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant64(__nt), __end)); (0, 247) } - pub(crate) fn __reduce821< + pub(crate) fn __reduce822< >( source_code: &str, mode: Mode, @@ -29914,15 +30039,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarUntypedParameter = Identifier => ActionFn(1490); + // StarUntypedParameter = Identifier => ActionFn(1492); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1490::<>(source_code, mode, __sym0); + let __nt = super::__action1492::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant63(__nt), __end)); (1, 248) } - pub(crate) fn __reduce822< + pub(crate) fn __reduce823< >( source_code: &str, mode: Mode, @@ -29931,15 +30056,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarUntypedParameter? = StarUntypedParameter => ActionFn(485); + // StarUntypedParameter? = StarUntypedParameter => ActionFn(488); let __sym0 = __pop_Variant63(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action485::<>(source_code, mode, __sym0); + let __nt = super::__action488::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant64(__nt), __end)); (1, 249) } - pub(crate) fn __reduce823< + pub(crate) fn __reduce824< >( source_code: &str, mode: Mode, @@ -29948,14 +30073,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarUntypedParameter? = => ActionFn(486); + // StarUntypedParameter? = => ActionFn(489); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action486::<>(source_code, mode, &__start, &__end); + let __nt = super::__action489::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant64(__nt), __end)); (0, 249) } - pub(crate) fn __reduce824< + pub(crate) fn __reduce825< >( source_code: &str, mode: Mode, @@ -29964,18 +30089,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = SmallStatement, ";", "\n" => ActionFn(1191); + // Statements = SmallStatement, ";", "\n" => ActionFn(1194); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1191::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + let __nt = super::__action1194::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (3, 250) } - pub(crate) fn __reduce825< + pub(crate) fn __reduce826< >( source_code: &str, mode: Mode, @@ -29984,7 +30109,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = ( ";")+, SmallStatement, ";", "\n" => ActionFn(1192); + // Statements = ( ";")+, SmallStatement, ";", "\n" => ActionFn(1195); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -29992,11 +30117,11 @@ mod __parse__Top { let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1192::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + let __nt = super::__action1195::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (4, 250) } - pub(crate) fn __reduce826< + pub(crate) fn __reduce827< >( source_code: &str, mode: Mode, @@ -30005,17 +30130,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = SmallStatement, "\n" => ActionFn(1193); + // Statements = SmallStatement, "\n" => ActionFn(1196); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1193::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + let __nt = super::__action1196::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (2, 250) } - pub(crate) fn __reduce827< + pub(crate) fn __reduce828< >( source_code: &str, mode: Mode, @@ -30024,18 +30149,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = ( ";")+, SmallStatement, "\n" => ActionFn(1194); + // Statements = ( ";")+, SmallStatement, "\n" => ActionFn(1197); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant37(__symbols); let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1194::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + let __nt = super::__action1197::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (3, 250) } - pub(crate) fn __reduce828< + pub(crate) fn __reduce829< >( source_code: &str, mode: Mode, @@ -30049,10 +30174,10 @@ mod __parse__Top { let __start = __sym0.0; let __end = __sym0.2; let __nt = super::__action10::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (1, 250) } - pub(crate) fn __reduce829< + pub(crate) fn __reduce830< >( source_code: &str, mode: Mode, @@ -30064,14 +30189,14 @@ mod __parse__Top { // Statements = Statements, CompoundStatement => ActionFn(11); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant37(__symbols); - let __sym0 = __pop_Variant94(__symbols); + let __sym0 = __pop_Variant97(__symbols); let __start = __sym0.0; let __end = __sym1.2; let __nt = super::__action11::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (2, 250) } - pub(crate) fn __reduce830< + pub(crate) fn __reduce831< >( source_code: &str, mode: Mode, @@ -30080,19 +30205,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = Statements, SmallStatement, ";", "\n" => ActionFn(1195); + // Statements = Statements, SmallStatement, ";", "\n" => ActionFn(1198); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant37(__symbols); - let __sym0 = __pop_Variant94(__symbols); + let __sym0 = __pop_Variant97(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1195::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + let __nt = super::__action1198::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (4, 250) } - pub(crate) fn __reduce831< + pub(crate) fn __reduce832< >( source_code: &str, mode: Mode, @@ -30101,20 +30226,20 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = Statements, ( ";")+, SmallStatement, ";", "\n" => ActionFn(1196); + // Statements = Statements, ( ";")+, SmallStatement, ";", "\n" => ActionFn(1199); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant37(__symbols); let __sym1 = __pop_Variant38(__symbols); - let __sym0 = __pop_Variant94(__symbols); + let __sym0 = __pop_Variant97(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1196::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + let __nt = super::__action1199::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (5, 250) } - pub(crate) fn __reduce832< + pub(crate) fn __reduce833< >( source_code: &str, mode: Mode, @@ -30123,18 +30248,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = Statements, SmallStatement, "\n" => ActionFn(1197); + // Statements = Statements, SmallStatement, "\n" => ActionFn(1200); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant37(__symbols); - let __sym0 = __pop_Variant94(__symbols); + let __sym0 = __pop_Variant97(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1197::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + let __nt = super::__action1200::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (3, 250) } - pub(crate) fn __reduce833< + pub(crate) fn __reduce834< >( source_code: &str, mode: Mode, @@ -30143,16 +30268,16 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = Statements, ( ";")+, SmallStatement, "\n" => ActionFn(1198); + // Statements = Statements, ( ";")+, SmallStatement, "\n" => ActionFn(1201); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant37(__symbols); let __sym1 = __pop_Variant38(__symbols); - let __sym0 = __pop_Variant94(__symbols); + let __sym0 = __pop_Variant97(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1198::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + let __nt = super::__action1201::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); (4, 250) } pub(crate) fn __reduce835< @@ -30164,49 +30289,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StringLiteral+ = StringLiteral => ActionFn(351); - let __sym0 = __pop_Variant69(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = super::__action351::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant95(__nt), __end)); - (1, 252) - } - pub(crate) fn __reduce836< - >( - source_code: &str, - mode: Mode, - __lookahead_start: Option<&TextSize>, - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, - _: core::marker::PhantomData<()>, - ) -> (usize, usize) - { - // StringLiteral+ = StringLiteral+, StringLiteral => ActionFn(352); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant69(__symbols); - let __sym0 = __pop_Variant95(__symbols); - let __start = __sym0.0; - let __end = __sym1.2; - let __nt = super::__action352::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant95(__nt), __end)); - (2, 252) - } - pub(crate) fn __reduce837< - >( - source_code: &str, - mode: Mode, - __lookahead_start: Option<&TextSize>, - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, - _: core::marker::PhantomData<()>, - ) -> (usize, usize) - { - // StringLiteralOrFString = StringLiteral => ActionFn(212); + // String = StringLiteralOrFString => ActionFn(935); let __sym0 = __pop_Variant69(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action212::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant69(__nt), __end)); - (1, 253) + let __nt = super::__action935::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 251) } pub(crate) fn __reduce838< >( @@ -30217,11 +30306,11 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StringLiteralOrFString = FStringExpr => ActionFn(213); + // StringLiteralOrFString = StringLiteral => ActionFn(215); let __sym0 = __pop_Variant69(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action213::<>(source_code, mode, __sym0); + let __nt = super::__action215::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant69(__nt), __end)); (1, 253) } @@ -30234,13 +30323,13 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StringLiteralOrFString+ = StringLiteralOrFString => ActionFn(349); + // StringLiteralOrFString = FStringExpr => ActionFn(216); let __sym0 = __pop_Variant69(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action349::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant95(__nt), __end)); - (1, 254) + let __nt = super::__action216::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant69(__nt), __end)); + (1, 253) } pub(crate) fn __reduce840< >( @@ -30251,34 +30340,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StringLiteralOrFString+ = StringLiteralOrFString+, StringLiteralOrFString => ActionFn(350); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant69(__symbols); - let __sym0 = __pop_Variant95(__symbols); - let __start = __sym0.0; - let __end = __sym1.2; - let __nt = super::__action350::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant95(__nt), __end)); - (2, 254) - } - pub(crate) fn __reduce841< - >( - source_code: &str, - mode: Mode, - __lookahead_start: Option<&TextSize>, - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, - _: core::marker::PhantomData<()>, - ) -> (usize, usize) - { - // Subscript = TestOrStarNamedExpr => ActionFn(209); + // Subscript = TestOrStarNamedExpr => ActionFn(210); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action209::<>(source_code, mode, __sym0); + let __nt = super::__action210::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 255) + (1, 254) } - pub(crate) fn __reduce842< + pub(crate) fn __reduce841< >( source_code: &str, mode: Mode, @@ -30287,19 +30357,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = Test<"all">, ":", Test<"all">, SliceOp => ActionFn(1731); + // Subscript = Test<"all">, ":", Test<"all">, SliceOp => ActionFn(1735); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant92(__symbols); + let __sym3 = __pop_Variant95(__symbols); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1731::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1735::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (4, 255) + (4, 254) } - pub(crate) fn __reduce843< + pub(crate) fn __reduce842< >( source_code: &str, mode: Mode, @@ -30308,18 +30378,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = Test<"all">, ":", SliceOp => ActionFn(1732); + // Subscript = Test<"all">, ":", SliceOp => ActionFn(1736); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant92(__symbols); + let __sym2 = __pop_Variant95(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1732::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1736::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 255) + (3, 254) } - pub(crate) fn __reduce844< + pub(crate) fn __reduce843< >( source_code: &str, mode: Mode, @@ -30328,18 +30398,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = ":", Test<"all">, SliceOp => ActionFn(1733); + // Subscript = ":", Test<"all">, SliceOp => ActionFn(1737); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant92(__symbols); + let __sym2 = __pop_Variant95(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1733::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1737::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 255) + (3, 254) } - pub(crate) fn __reduce845< + pub(crate) fn __reduce844< >( source_code: &str, mode: Mode, @@ -30348,17 +30418,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = ":", SliceOp => ActionFn(1734); + // Subscript = ":", SliceOp => ActionFn(1738); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant92(__symbols); + let __sym1 = __pop_Variant95(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1734::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1738::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 255) + (2, 254) } - pub(crate) fn __reduce846< + pub(crate) fn __reduce845< >( source_code: &str, mode: Mode, @@ -30367,18 +30437,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = Test<"all">, ":", Test<"all"> => ActionFn(1735); + // Subscript = Test<"all">, ":", Test<"all"> => ActionFn(1739); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1735::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1739::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 255) + (3, 254) } - pub(crate) fn __reduce847< + pub(crate) fn __reduce846< >( source_code: &str, mode: Mode, @@ -30387,17 +30457,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = Test<"all">, ":" => ActionFn(1736); + // Subscript = Test<"all">, ":" => ActionFn(1740); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1736::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1740::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 255) + (2, 254) } - pub(crate) fn __reduce848< + pub(crate) fn __reduce847< >( source_code: &str, mode: Mode, @@ -30406,17 +30476,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = ":", Test<"all"> => ActionFn(1737); + // Subscript = ":", Test<"all"> => ActionFn(1741); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1737::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1741::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 255) + (2, 254) } - pub(crate) fn __reduce849< + pub(crate) fn __reduce848< >( source_code: &str, mode: Mode, @@ -30425,15 +30495,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = ":" => ActionFn(1738); + // Subscript = ":" => ActionFn(1742); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1738::<>(source_code, mode, __sym0); + let __nt = super::__action1742::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 255) + (1, 254) } - pub(crate) fn __reduce850< + pub(crate) fn __reduce849< >( source_code: &str, mode: Mode, @@ -30442,15 +30512,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SubscriptList = Subscript => ActionFn(206); + // SubscriptList = Subscript => ActionFn(207); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action206::<>(source_code, mode, __sym0); + let __nt = super::__action207::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 256) + (1, 255) } - pub(crate) fn __reduce851< + pub(crate) fn __reduce850< >( source_code: &str, mode: Mode, @@ -30459,17 +30529,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SubscriptList = Subscript, "," => ActionFn(1492); + // SubscriptList = Subscript, "," => ActionFn(1496); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1492::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1496::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 256) + (2, 255) } - pub(crate) fn __reduce852< + pub(crate) fn __reduce851< >( source_code: &str, mode: Mode, @@ -30478,17 +30548,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SubscriptList = TwoOrMore, "," => ActionFn(1493); + // SubscriptList = TwoOrMoreSep, "," => ActionFn(1497); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1493::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1497::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 256) + (2, 255) } - pub(crate) fn __reduce853< + pub(crate) fn __reduce852< >( source_code: &str, mode: Mode, @@ -30497,15 +30567,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SubscriptList = TwoOrMore => ActionFn(1494); + // SubscriptList = TwoOrMoreSep => ActionFn(1498); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1494::<>(source_code, mode, __sym0); + let __nt = super::__action1498::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 256) + (1, 255) } - pub(crate) fn __reduce854< + pub(crate) fn __reduce853< >( source_code: &str, mode: Mode, @@ -30514,18 +30584,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Suite = SmallStatement, ";", "\n" => ActionFn(1199); + // Suite = SmallStatement, ";", "\n" => ActionFn(1202); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1199::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1202::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (3, 257) + (3, 256) } - pub(crate) fn __reduce855< + pub(crate) fn __reduce854< >( source_code: &str, mode: Mode, @@ -30534,7 +30604,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Suite = ( ";")+, SmallStatement, ";", "\n" => ActionFn(1200); + // Suite = ( ";")+, SmallStatement, ";", "\n" => ActionFn(1203); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -30542,11 +30612,11 @@ mod __parse__Top { let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1200::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1203::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (4, 257) + (4, 256) } - pub(crate) fn __reduce856< + pub(crate) fn __reduce855< >( source_code: &str, mode: Mode, @@ -30555,17 +30625,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Suite = SmallStatement, "\n" => ActionFn(1201); + // Suite = SmallStatement, "\n" => ActionFn(1204); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1201::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1204::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (2, 257) + (2, 256) } - pub(crate) fn __reduce857< + pub(crate) fn __reduce856< >( source_code: &str, mode: Mode, @@ -30574,18 +30644,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Suite = ( ";")+, SmallStatement, "\n" => ActionFn(1202); + // Suite = ( ";")+, SmallStatement, "\n" => ActionFn(1205); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant37(__symbols); let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1202::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1205::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (3, 257) + (3, 256) } - pub(crate) fn __reduce858< + pub(crate) fn __reduce857< >( source_code: &str, mode: Mode, @@ -30597,16 +30667,16 @@ mod __parse__Top { // Suite = "\n", Indent, Statements, Dedent => ActionFn(8); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant94(__symbols); + let __sym2 = __pop_Variant97(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; let __nt = super::__action8::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (4, 257) + (4, 256) } - pub(crate) fn __reduce859< + pub(crate) fn __reduce858< >( source_code: &str, mode: Mode, @@ -30615,18 +30685,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Term<"all"> = Term<"all">, MulOp, Factor<"all"> => ActionFn(1495); + // Term<"all"> = Term<"all">, MulOp, Factor<"all"> => ActionFn(1499); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant49(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1495::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1499::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 258) + (3, 257) } - pub(crate) fn __reduce860< + pub(crate) fn __reduce859< >( source_code: &str, mode: Mode, @@ -30635,15 +30705,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Term<"all"> = Factor<"all"> => ActionFn(522); + // Term<"all"> = Factor<"all"> => ActionFn(525); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action522::<>(source_code, mode, __sym0); + let __nt = super::__action525::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 258) + (1, 257) } - pub(crate) fn __reduce861< + pub(crate) fn __reduce860< >( source_code: &str, mode: Mode, @@ -30652,18 +30722,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Term<"no-withitems"> = Term<"all">, MulOp, Factor<"all"> => ActionFn(1496); + // Term<"no-withitems"> = Term<"all">, MulOp, Factor<"all"> => ActionFn(1500); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant49(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1496::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1500::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 259) + (3, 258) } - pub(crate) fn __reduce862< + pub(crate) fn __reduce861< >( source_code: &str, mode: Mode, @@ -30672,15 +30742,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Term<"no-withitems"> = Factor<"no-withitems"> => ActionFn(575); + // Term<"no-withitems"> = Factor<"no-withitems"> => ActionFn(578); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action575::<>(source_code, mode, __sym0); + let __nt = super::__action578::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 259) + (1, 258) } - pub(crate) fn __reduce863< + pub(crate) fn __reduce862< >( source_code: &str, mode: Mode, @@ -30689,7 +30759,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all"> = OrTest<"all">, "if", OrTest<"all">, "else", Test<"all"> => ActionFn(1497); + // Test<"all"> = OrTest<"all">, "if", OrTest<"all">, "else", Test<"all"> => ActionFn(1501); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -30698,11 +30768,11 @@ mod __parse__Top { let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1497::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1501::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (5, 260) + (5, 259) } - pub(crate) fn __reduce864< + pub(crate) fn __reduce863< >( source_code: &str, mode: Mode, @@ -30711,15 +30781,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all"> = OrTest<"all"> => ActionFn(401); + // Test<"all"> = OrTest<"all"> => ActionFn(404); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action401::<>(source_code, mode, __sym0); + let __nt = super::__action404::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 260) + (1, 259) } - pub(crate) fn __reduce865< + pub(crate) fn __reduce864< >( source_code: &str, mode: Mode, @@ -30728,15 +30798,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all"> = LambdaDef => ActionFn(402); + // Test<"all"> = LambdaDef => ActionFn(405); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action402::<>(source_code, mode, __sym0); + let __nt = super::__action405::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 260) + (1, 259) } - pub(crate) fn __reduce866< + pub(crate) fn __reduce865< >( source_code: &str, mode: Mode, @@ -30745,15 +30815,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all">? = Test<"all"> => ActionFn(322); + // Test<"all">? = Test<"all"> => ActionFn(327); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action322::<>(source_code, mode, __sym0); + let __nt = super::__action327::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 261) + (1, 260) } - pub(crate) fn __reduce867< + pub(crate) fn __reduce866< >( source_code: &str, mode: Mode, @@ -30762,14 +30832,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all">? = => ActionFn(323); + // Test<"all">? = => ActionFn(328); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action323::<>(source_code, mode, &__start, &__end); + let __nt = super::__action328::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (0, 261) + (0, 260) } - pub(crate) fn __reduce868< + pub(crate) fn __reduce867< >( source_code: &str, mode: Mode, @@ -30778,7 +30848,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"no-withitems"> = OrTest<"all">, "if", OrTest<"all">, "else", Test<"all"> => ActionFn(1498); + // Test<"no-withitems"> = OrTest<"all">, "if", OrTest<"all">, "else", Test<"all"> => ActionFn(1502); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -30787,11 +30857,11 @@ mod __parse__Top { let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1498::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1502::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (5, 262) + (5, 261) } - pub(crate) fn __reduce869< + pub(crate) fn __reduce868< >( source_code: &str, mode: Mode, @@ -30800,15 +30870,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"no-withitems"> = OrTest<"no-withitems"> => ActionFn(433); + // Test<"no-withitems"> = OrTest<"no-withitems"> => ActionFn(436); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action433::<>(source_code, mode, __sym0); + let __nt = super::__action436::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 262) + (1, 261) } - pub(crate) fn __reduce870< + pub(crate) fn __reduce869< >( source_code: &str, mode: Mode, @@ -30817,15 +30887,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"no-withitems"> = LambdaDef => ActionFn(434); + // Test<"no-withitems"> = LambdaDef => ActionFn(437); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action434::<>(source_code, mode, __sym0); + let __nt = super::__action437::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 262) + (1, 261) } - pub(crate) fn __reduce871< + pub(crate) fn __reduce870< >( source_code: &str, mode: Mode, @@ -30834,15 +30904,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestList = GenericList => ActionFn(232); + // TestList = GenericList => ActionFn(235); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action232::<>(source_code, mode, __sym0); + let __nt = super::__action235::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 263) + (1, 262) } - pub(crate) fn __reduce872< + pub(crate) fn __reduce871< >( source_code: &str, mode: Mode, @@ -30851,15 +30921,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestList? = GenericList => ActionFn(1743); + // TestList? = GenericList => ActionFn(1747); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1743::<>(source_code, mode, __sym0); + let __nt = super::__action1747::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 264) + (1, 263) } - pub(crate) fn __reduce873< + pub(crate) fn __reduce872< >( source_code: &str, mode: Mode, @@ -30868,14 +30938,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestList? = => ActionFn(397); + // TestList? = => ActionFn(400); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action397::<>(source_code, mode, &__start, &__end); + let __nt = super::__action400::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (0, 264) + (0, 263) } - pub(crate) fn __reduce874< + pub(crate) fn __reduce873< >( source_code: &str, mode: Mode, @@ -30884,15 +30954,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestListOrYieldExpr = GenericList => ActionFn(1744); + // TestListOrYieldExpr = GenericList => ActionFn(1748); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1744::<>(source_code, mode, __sym0); + let __nt = super::__action1748::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 265) + (1, 264) } - pub(crate) fn __reduce875< + pub(crate) fn __reduce874< >( source_code: &str, mode: Mode, @@ -30907,9 +30977,9 @@ mod __parse__Top { let __end = __sym0.2; let __nt = super::__action32::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 265) + (1, 264) } - pub(crate) fn __reduce876< + pub(crate) fn __reduce875< >( source_code: &str, mode: Mode, @@ -30924,9 +30994,9 @@ mod __parse__Top { let __end = __sym0.2; let __nt = super::__action34::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 266) + (1, 265) } - pub(crate) fn __reduce877< + pub(crate) fn __reduce876< >( source_code: &str, mode: Mode, @@ -30941,9 +31011,9 @@ mod __parse__Top { let __end = __sym0.2; let __nt = super::__action35::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 266) + (1, 265) } - pub(crate) fn __reduce878< + pub(crate) fn __reduce877< >( source_code: &str, mode: Mode, @@ -30952,15 +31022,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestOrStarExprList = GenericList => ActionFn(1745); + // TestOrStarExprList = GenericList => ActionFn(1749); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1745::<>(source_code, mode, __sym0); + let __nt = super::__action1749::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 267) + (1, 266) } - pub(crate) fn __reduce879< + pub(crate) fn __reduce878< >( source_code: &str, mode: Mode, @@ -30975,9 +31045,9 @@ mod __parse__Top { let __end = __sym0.2; let __nt = super::__action38::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 268) + (1, 267) } - pub(crate) fn __reduce880< + pub(crate) fn __reduce879< >( source_code: &str, mode: Mode, @@ -30992,9 +31062,9 @@ mod __parse__Top { let __end = __sym0.2; let __nt = super::__action39::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 268) + (1, 267) } - pub(crate) fn __reduce881< + pub(crate) fn __reduce880< >( source_code: &str, mode: Mode, @@ -31003,17 +31073,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Top = StartModule, Program => ActionFn(1499); + // Top = StartModule, Program => ActionFn(1503); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant25(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1499::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant96(__nt), __end)); - (2, 269) + let __nt = super::__action1503::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant98(__nt), __end)); + (2, 268) } - pub(crate) fn __reduce882< + pub(crate) fn __reduce881< >( source_code: &str, mode: Mode, @@ -31022,17 +31092,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Top = StartExpression, GenericList => ActionFn(1746); + // Top = StartExpression, GenericList => ActionFn(1750); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1746::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant96(__nt), __end)); - (2, 269) + let __nt = super::__action1750::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant98(__nt), __end)); + (2, 268) } - pub(crate) fn __reduce883< + pub(crate) fn __reduce882< >( source_code: &str, mode: Mode, @@ -31041,18 +31111,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Top = StartExpression, GenericList, ("\n")+ => ActionFn(1747); + // Top = StartExpression, GenericList, ("\n")+ => ActionFn(1751); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant22(__symbols); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1747::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant96(__nt), __end)); - (3, 269) + let __nt = super::__action1751::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant98(__nt), __end)); + (3, 268) } - pub(crate) fn __reduce884< + pub(crate) fn __reduce883< >( source_code: &str, mode: Mode, @@ -31061,7 +31131,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptClause+, "else", ":", Suite, "finally", ":", Suite => ActionFn(1502); + // TryStatement = "try", ":", Suite, ExceptClause+, "else", ":", Suite, "finally", ":", Suite => ActionFn(1506); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant25(__symbols); let __sym8 = __pop_Variant0(__symbols); @@ -31075,11 +31145,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = super::__action1502::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); + let __nt = super::__action1506::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (10, 270) + (10, 269) } - pub(crate) fn __reduce885< + pub(crate) fn __reduce884< >( source_code: &str, mode: Mode, @@ -31088,7 +31158,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptClause+, "else", ":", Suite => ActionFn(1503); + // TryStatement = "try", ":", Suite, ExceptClause+, "else", ":", Suite => ActionFn(1507); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -31099,11 +31169,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1503::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1507::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (7, 270) + (7, 269) } - pub(crate) fn __reduce886< + pub(crate) fn __reduce885< >( source_code: &str, mode: Mode, @@ -31112,7 +31182,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptClause+, "finally", ":", Suite => ActionFn(1504); + // TryStatement = "try", ":", Suite, ExceptClause+, "finally", ":", Suite => ActionFn(1508); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -31123,11 +31193,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1504::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1508::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (7, 270) + (7, 269) } - pub(crate) fn __reduce887< + pub(crate) fn __reduce886< >( source_code: &str, mode: Mode, @@ -31136,7 +31206,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptClause+ => ActionFn(1505); + // TryStatement = "try", ":", Suite, ExceptClause+ => ActionFn(1509); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant66(__symbols); let __sym2 = __pop_Variant25(__symbols); @@ -31144,11 +31214,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1505::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1509::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (4, 270) + (4, 269) } - pub(crate) fn __reduce888< + pub(crate) fn __reduce887< >( source_code: &str, mode: Mode, @@ -31157,7 +31227,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptStarClause+, "else", ":", Suite, "finally", ":", Suite => ActionFn(1506); + // TryStatement = "try", ":", Suite, ExceptStarClause+, "else", ":", Suite, "finally", ":", Suite => ActionFn(1510); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant25(__symbols); let __sym8 = __pop_Variant0(__symbols); @@ -31171,11 +31241,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = super::__action1506::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); + let __nt = super::__action1510::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (10, 270) + (10, 269) } - pub(crate) fn __reduce889< + pub(crate) fn __reduce888< >( source_code: &str, mode: Mode, @@ -31184,7 +31254,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptStarClause+, "else", ":", Suite => ActionFn(1507); + // TryStatement = "try", ":", Suite, ExceptStarClause+, "else", ":", Suite => ActionFn(1511); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -31195,11 +31265,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1507::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1511::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (7, 270) + (7, 269) } - pub(crate) fn __reduce890< + pub(crate) fn __reduce889< >( source_code: &str, mode: Mode, @@ -31208,7 +31278,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptStarClause+, "finally", ":", Suite => ActionFn(1508); + // TryStatement = "try", ":", Suite, ExceptStarClause+, "finally", ":", Suite => ActionFn(1512); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -31219,11 +31289,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1508::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1512::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (7, 270) + (7, 269) } - pub(crate) fn __reduce891< + pub(crate) fn __reduce890< >( source_code: &str, mode: Mode, @@ -31232,7 +31302,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptStarClause+ => ActionFn(1509); + // TryStatement = "try", ":", Suite, ExceptStarClause+ => ActionFn(1513); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant66(__symbols); let __sym2 = __pop_Variant25(__symbols); @@ -31240,11 +31310,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1509::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1513::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (4, 270) + (4, 269) } - pub(crate) fn __reduce892< + pub(crate) fn __reduce891< >( source_code: &str, mode: Mode, @@ -31253,7 +31323,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, "finally", ":", Suite => ActionFn(1135); + // TryStatement = "try", ":", Suite, "finally", ":", Suite => ActionFn(1138); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -31263,9 +31333,28 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1135::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1138::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (6, 270) + (6, 269) + } + pub(crate) fn __reduce892< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // TwoOrMore = StringLiteral, StringLiteral => ActionFn(354); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant69(__symbols); + let __sym0 = __pop_Variant69(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action354::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant99(__nt), __end)); + (2, 270) } pub(crate) fn __reduce893< >( @@ -31276,18 +31365,75 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = ClosedPattern, "|", ClosedPattern => ActionFn(357); + // TwoOrMore = TwoOrMore, StringLiteral => ActionFn(355); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant69(__symbols); + let __sym0 = __pop_Variant99(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action355::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant99(__nt), __end)); + (2, 270) + } + pub(crate) fn __reduce894< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // TwoOrMore = StringLiteralOrFString, StringLiteralOrFString => ActionFn(275); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant69(__symbols); + let __sym0 = __pop_Variant69(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action275::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant99(__nt), __end)); + (2, 271) + } + pub(crate) fn __reduce895< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // TwoOrMore = TwoOrMore, StringLiteralOrFString => ActionFn(276); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant69(__symbols); + let __sym0 = __pop_Variant99(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action276::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant99(__nt), __end)); + (2, 271) + } + pub(crate) fn __reduce896< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // TwoOrMoreSep = ClosedPattern, "|", ClosedPattern => ActionFn(360); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action357::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action360::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); - (3, 271) + (3, 272) } - pub(crate) fn __reduce894< + pub(crate) fn __reduce897< >( source_code: &str, mode: Mode, @@ -31296,18 +31442,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TwoOrMore, "|", ClosedPattern => ActionFn(358); + // TwoOrMoreSep = TwoOrMoreSep, "|", ClosedPattern => ActionFn(361); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action358::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action361::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); - (3, 271) + (3, 272) } - pub(crate) fn __reduce895< + pub(crate) fn __reduce898< >( source_code: &str, mode: Mode, @@ -31316,18 +31462,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = Pattern, ",", Pattern => ActionFn(359); + // TwoOrMoreSep = Pattern, ",", Pattern => ActionFn(362); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action359::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action362::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); - (3, 272) + (3, 273) } - pub(crate) fn __reduce896< + pub(crate) fn __reduce899< >( source_code: &str, mode: Mode, @@ -31336,18 +31482,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TwoOrMore, ",", Pattern => ActionFn(360); + // TwoOrMoreSep = TwoOrMoreSep, ",", Pattern => ActionFn(363); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action360::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action363::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant53(__nt), __end)); - (3, 272) + (3, 273) } - pub(crate) fn __reduce897< + pub(crate) fn __reduce900< >( source_code: &str, mode: Mode, @@ -31356,18 +31502,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = Subscript, ",", Subscript => ActionFn(274); + // TwoOrMoreSep = Subscript, ",", Subscript => ActionFn(279); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action274::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action279::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); - (3, 273) + (3, 274) } - pub(crate) fn __reduce898< + pub(crate) fn __reduce901< >( source_code: &str, mode: Mode, @@ -31376,18 +31522,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TwoOrMore, ",", Subscript => ActionFn(275); + // TwoOrMoreSep = TwoOrMoreSep, ",", Subscript => ActionFn(280); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action275::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action280::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); - (3, 273) + (3, 274) } - pub(crate) fn __reduce899< + pub(crate) fn __reduce902< >( source_code: &str, mode: Mode, @@ -31396,18 +31542,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TestOrStarNamedExpr, ",", TestOrStarNamedExpr => ActionFn(364); + // TwoOrMoreSep = TestOrStarNamedExpr, ",", TestOrStarNamedExpr => ActionFn(367); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action364::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action367::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); - (3, 274) + (3, 275) } - pub(crate) fn __reduce900< + pub(crate) fn __reduce903< >( source_code: &str, mode: Mode, @@ -31416,18 +31562,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TwoOrMore, ",", TestOrStarNamedExpr => ActionFn(365); + // TwoOrMoreSep = TwoOrMoreSep, ",", TestOrStarNamedExpr => ActionFn(368); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action365::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action368::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant33(__nt), __end)); - (3, 274) + (3, 275) } - pub(crate) fn __reduce901< + pub(crate) fn __reduce904< >( source_code: &str, mode: Mode, @@ -31436,15 +31582,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeAliasName = Identifier => ActionFn(1510); + // TypeAliasName = Identifier => ActionFn(1514); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1510::<>(source_code, mode, __sym0); + let __nt = super::__action1514::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); - (1, 275) + (1, 276) } - pub(crate) fn __reduce902< + pub(crate) fn __reduce905< >( source_code: &str, mode: Mode, @@ -31453,20 +31599,20 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeAliasStatement = "type", TypeAliasName, TypeParams, "=", Test<"all"> => ActionFn(1779); + // TypeAliasStatement = "type", TypeAliasName, TypeParams, "=", Test<"all"> => ActionFn(1783); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant101(__symbols); let __sym1 = __pop_Variant44(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1779::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1783::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (5, 276) + (5, 277) } - pub(crate) fn __reduce903< + pub(crate) fn __reduce906< >( source_code: &str, mode: Mode, @@ -31475,7 +31621,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeAliasStatement = "type", TypeAliasName, "=", Test<"all"> => ActionFn(1780); + // TypeAliasStatement = "type", TypeAliasName, "=", Test<"all"> => ActionFn(1784); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -31483,11 +31629,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1780::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1784::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (4, 276) + (4, 277) } - pub(crate) fn __reduce904< + pub(crate) fn __reduce907< >( source_code: &str, mode: Mode, @@ -31496,18 +31642,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParam = Identifier, ":", Test<"all"> => ActionFn(1512); + // TypeParam = Identifier, ":", Test<"all"> => ActionFn(1516); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1512::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant97(__nt), __end)); - (3, 277) + let __nt = super::__action1516::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant100(__nt), __end)); + (3, 278) } - pub(crate) fn __reduce905< + pub(crate) fn __reduce908< >( source_code: &str, mode: Mode, @@ -31516,15 +31662,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParam = Identifier => ActionFn(1513); + // TypeParam = Identifier => ActionFn(1517); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1513::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant97(__nt), __end)); - (1, 277) + let __nt = super::__action1517::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant100(__nt), __end)); + (1, 278) } - pub(crate) fn __reduce906< + pub(crate) fn __reduce909< >( source_code: &str, mode: Mode, @@ -31533,17 +31679,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParam = "*", Identifier => ActionFn(1514); + // TypeParam = "*", Identifier => ActionFn(1518); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1514::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant97(__nt), __end)); - (2, 277) + let __nt = super::__action1518::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant100(__nt), __end)); + (2, 278) } - pub(crate) fn __reduce907< + pub(crate) fn __reduce910< >( source_code: &str, mode: Mode, @@ -31552,17 +31698,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParam = "**", Identifier => ActionFn(1515); + // TypeParam = "**", Identifier => ActionFn(1519); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1515::<>(source_code, mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant97(__nt), __end)); - (2, 277) + let __nt = super::__action1519::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant100(__nt), __end)); + (2, 278) } - pub(crate) fn __reduce908< + pub(crate) fn __reduce911< >( source_code: &str, mode: Mode, @@ -31571,19 +31717,19 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParams = "[", OneOrMore, ",", "]" => ActionFn(1516); + // TypeParams = "[", OneOrMore, ",", "]" => ActionFn(1520); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant86(__symbols); + let __sym1 = __pop_Variant89(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1516::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant98(__nt), __end)); - (4, 278) + let __nt = super::__action1520::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant101(__nt), __end)); + (4, 279) } - pub(crate) fn __reduce909< + pub(crate) fn __reduce912< >( source_code: &str, mode: Mode, @@ -31592,18 +31738,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParams = "[", OneOrMore, "]" => ActionFn(1517); + // TypeParams = "[", OneOrMore, "]" => ActionFn(1521); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant86(__symbols); + let __sym1 = __pop_Variant89(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1517::<>(source_code, mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant98(__nt), __end)); - (3, 278) + let __nt = super::__action1521::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant101(__nt), __end)); + (3, 279) } - pub(crate) fn __reduce910< + pub(crate) fn __reduce913< >( source_code: &str, mode: Mode, @@ -31612,15 +31758,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParams? = TypeParams => ActionFn(304); - let __sym0 = __pop_Variant98(__symbols); + // TypeParams? = TypeParams => ActionFn(309); + let __sym0 = __pop_Variant101(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action304::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant99(__nt), __end)); - (1, 279) + let __nt = super::__action309::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant102(__nt), __end)); + (1, 280) } - pub(crate) fn __reduce911< + pub(crate) fn __reduce914< >( source_code: &str, mode: Mode, @@ -31629,14 +31775,14 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParams? = => ActionFn(305); + // TypeParams? = => ActionFn(310); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action305::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant99(__nt), __end)); - (0, 279) + let __nt = super::__action310::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant102(__nt), __end)); + (0, 280) } - pub(crate) fn __reduce912< + pub(crate) fn __reduce915< >( source_code: &str, mode: Mode, @@ -31645,18 +31791,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypedParameter = Identifier, ":", Test<"all"> => ActionFn(1518); + // TypedParameter = Identifier, ":", Test<"all"> => ActionFn(1522); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1518::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1522::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (3, 280) + (3, 281) } - pub(crate) fn __reduce913< + pub(crate) fn __reduce916< >( source_code: &str, mode: Mode, @@ -31665,15 +31811,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypedParameter = Identifier => ActionFn(1519); + // TypedParameter = Identifier => ActionFn(1523); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1519::<>(source_code, mode, __sym0); + let __nt = super::__action1523::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (1, 280) + (1, 281) } - pub(crate) fn __reduce914< + pub(crate) fn __reduce917< >( source_code: &str, mode: Mode, @@ -31682,15 +31828,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // UnaryOp = "+" => ActionFn(203); + // UnaryOp = "+" => ActionFn(204); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action203::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant100(__nt), __end)); - (1, 281) + let __nt = super::__action204::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant103(__nt), __end)); + (1, 282) } - pub(crate) fn __reduce915< + pub(crate) fn __reduce918< >( source_code: &str, mode: Mode, @@ -31699,15 +31845,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // UnaryOp = "-" => ActionFn(204); + // UnaryOp = "-" => ActionFn(205); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action204::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant100(__nt), __end)); - (1, 281) + let __nt = super::__action205::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant103(__nt), __end)); + (1, 282) } - pub(crate) fn __reduce916< + pub(crate) fn __reduce919< >( source_code: &str, mode: Mode, @@ -31716,15 +31862,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // UnaryOp = "~" => ActionFn(205); + // UnaryOp = "~" => ActionFn(206); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action205::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant100(__nt), __end)); - (1, 281) + let __nt = super::__action206::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant103(__nt), __end)); + (1, 282) } - pub(crate) fn __reduce917< + pub(crate) fn __reduce920< >( source_code: &str, mode: Mode, @@ -31733,15 +31879,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // UntypedParameter = Identifier => ActionFn(1520); + // UntypedParameter = Identifier => ActionFn(1524); let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1520::<>(source_code, mode, __sym0); + let __nt = super::__action1524::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (1, 282) + (1, 283) } - pub(crate) fn __reduce918< + pub(crate) fn __reduce921< >( source_code: &str, mode: Mode, @@ -31750,15 +31896,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ValuePattern = MatchNameOrAttr => ActionFn(1521); + // ValuePattern = MatchNameOrAttr => ActionFn(1525); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1521::<>(source_code, mode, __sym0); + let __nt = super::__action1525::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant35(__nt), __end)); - (1, 283) + (1, 284) } - pub(crate) fn __reduce919< + pub(crate) fn __reduce922< >( source_code: &str, mode: Mode, @@ -31767,7 +31913,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WhileStatement = "while", NamedExpressionTest, ":", Suite, "else", ":", Suite => ActionFn(1132); + // WhileStatement = "while", NamedExpressionTest, ":", Suite, "else", ":", Suite => ActionFn(1135); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -31778,11 +31924,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1132::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1135::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (7, 284) + (7, 285) } - pub(crate) fn __reduce920< + pub(crate) fn __reduce923< >( source_code: &str, mode: Mode, @@ -31791,7 +31937,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WhileStatement = "while", NamedExpressionTest, ":", Suite => ActionFn(1133); + // WhileStatement = "while", NamedExpressionTest, ":", Suite => ActionFn(1136); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -31799,11 +31945,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1133::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1136::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (4, 284) + (4, 285) } - pub(crate) fn __reduce921< + pub(crate) fn __reduce924< >( source_code: &str, mode: Mode, @@ -31812,15 +31958,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItem<"all"> = Test<"all"> => ActionFn(317); + // WithItem<"all"> = Test<"all"> => ActionFn(322); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action317::<>(source_code, mode, __sym0); + let __nt = super::__action322::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (1, 285) + (1, 286) } - pub(crate) fn __reduce922< + pub(crate) fn __reduce925< >( source_code: &str, mode: Mode, @@ -31829,15 +31975,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItem<"all"> = WithItemAs => ActionFn(318); + // WithItem<"all"> = WithItemAs => ActionFn(323); let __sym0 = __pop_Variant18(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action318::<>(source_code, mode, __sym0); + let __nt = super::__action323::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (1, 285) + (1, 286) } - pub(crate) fn __reduce923< + pub(crate) fn __reduce926< >( source_code: &str, mode: Mode, @@ -31846,15 +31992,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItem<"no-withitems"> = Test<"no-withitems"> => ActionFn(312); + // WithItem<"no-withitems"> = Test<"no-withitems"> => ActionFn(317); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action312::<>(source_code, mode, __sym0); + let __nt = super::__action317::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (1, 286) + (1, 287) } - pub(crate) fn __reduce924< + pub(crate) fn __reduce927< >( source_code: &str, mode: Mode, @@ -31863,15 +32009,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItem<"no-withitems"> = WithItemAs => ActionFn(313); + // WithItem<"no-withitems"> = WithItemAs => ActionFn(318); let __sym0 = __pop_Variant18(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action313::<>(source_code, mode, __sym0); + let __nt = super::__action318::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (1, 286) + (1, 287) } - pub(crate) fn __reduce925< + pub(crate) fn __reduce928< >( source_code: &str, mode: Mode, @@ -31880,18 +32026,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItemAs = Test<"all">, "as", Expression<"all"> => ActionFn(1522); + // WithItemAs = Test<"all">, "as", Expression<"all"> => ActionFn(1526); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1522::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1526::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (3, 287) + (3, 288) } - pub(crate) fn __reduce926< + pub(crate) fn __reduce929< >( source_code: &str, mode: Mode, @@ -31900,7 +32046,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", ")" => ActionFn(1206); + // WithItems = "(", OneOrMore>, ",", ")" => ActionFn(1209); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -31908,11 +32054,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1206::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1209::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (4, 288) + (4, 289) } - pub(crate) fn __reduce927< + pub(crate) fn __reduce930< >( source_code: &str, mode: Mode, @@ -31921,18 +32067,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ")" => ActionFn(1207); + // WithItems = "(", OneOrMore>, ")" => ActionFn(1210); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1207::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1210::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (3, 288) + (3, 289) } - pub(crate) fn __reduce928< + pub(crate) fn __reduce931< >( source_code: &str, mode: Mode, @@ -31941,7 +32087,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", WithItemAs, ",", ")" => ActionFn(1209); + // WithItems = "(", OneOrMore>, ",", WithItemAs, ",", ")" => ActionFn(1212); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); @@ -31951,11 +32097,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1209::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1212::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (6, 288) + (6, 289) } - pub(crate) fn __reduce929< + pub(crate) fn __reduce932< >( source_code: &str, mode: Mode, @@ -31964,7 +32110,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", WithItemAs, ",", ")" => ActionFn(1210); + // WithItems = "(", WithItemAs, ",", ")" => ActionFn(1213); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -31972,11 +32118,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1210::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1213::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (4, 288) + (4, 289) } - pub(crate) fn __reduce930< + pub(crate) fn __reduce933< >( source_code: &str, mode: Mode, @@ -31985,7 +32131,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", WithItemAs, ("," >)+, ",", ")" => ActionFn(1211); + // WithItems = "(", OneOrMore>, ",", WithItemAs, ("," >)+, ",", ")" => ActionFn(1214); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); @@ -31996,11 +32142,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1211::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action1214::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (7, 288) + (7, 289) } - pub(crate) fn __reduce931< + pub(crate) fn __reduce934< >( source_code: &str, mode: Mode, @@ -32009,7 +32155,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", WithItemAs, ("," >)+, ",", ")" => ActionFn(1212); + // WithItems = "(", WithItemAs, ("," >)+, ",", ")" => ActionFn(1215); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -32018,11 +32164,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1212::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1215::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (5, 288) + (5, 289) } - pub(crate) fn __reduce932< + pub(crate) fn __reduce935< >( source_code: &str, mode: Mode, @@ -32031,7 +32177,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", WithItemAs, ")" => ActionFn(1213); + // WithItems = "(", OneOrMore>, ",", WithItemAs, ")" => ActionFn(1216); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant18(__symbols); @@ -32040,11 +32186,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1213::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action1216::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (5, 288) + (5, 289) } - pub(crate) fn __reduce933< + pub(crate) fn __reduce936< >( source_code: &str, mode: Mode, @@ -32053,18 +32199,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", WithItemAs, ")" => ActionFn(1214); + // WithItems = "(", WithItemAs, ")" => ActionFn(1217); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1214::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1217::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (3, 288) + (3, 289) } - pub(crate) fn __reduce934< + pub(crate) fn __reduce937< >( source_code: &str, mode: Mode, @@ -32073,7 +32219,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", WithItemAs, ("," >)+, ")" => ActionFn(1215); + // WithItems = "(", OneOrMore>, ",", WithItemAs, ("," >)+, ")" => ActionFn(1218); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant19(__symbols); @@ -32083,11 +32229,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1215::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action1218::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (6, 288) + (6, 289) } - pub(crate) fn __reduce935< + pub(crate) fn __reduce938< >( source_code: &str, mode: Mode, @@ -32096,7 +32242,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", WithItemAs, ("," >)+, ")" => ActionFn(1216); + // WithItems = "(", WithItemAs, ("," >)+, ")" => ActionFn(1219); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant19(__symbols); @@ -32104,11 +32250,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1216::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action1219::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (4, 288) + (4, 289) } - pub(crate) fn __reduce936< + pub(crate) fn __reduce939< >( source_code: &str, mode: Mode, @@ -32117,15 +32263,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = WithItem<"no-withitems"> => ActionFn(158); + // WithItems = WithItem<"no-withitems"> => ActionFn(159); let __sym0 = __pop_Variant18(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action158::<>(source_code, mode, __sym0); + let __nt = super::__action159::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (1, 288) + (1, 289) } - pub(crate) fn __reduce937< + pub(crate) fn __reduce940< >( source_code: &str, mode: Mode, @@ -32134,17 +32280,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = WithItem<"all">, ("," >)+ => ActionFn(159); + // WithItems = WithItem<"all">, ("," >)+ => ActionFn(160); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant19(__symbols); let __sym0 = __pop_Variant18(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action159::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action160::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (2, 288) + (2, 289) } - pub(crate) fn __reduce938< + pub(crate) fn __reduce941< >( source_code: &str, mode: Mode, @@ -32153,15 +32299,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItemsNoAs = OneOrMore> => ActionFn(160); + // WithItemsNoAs = OneOrMore> => ActionFn(161); let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action160::<>(source_code, mode, __sym0); + let __nt = super::__action161::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (1, 289) + (1, 290) } - pub(crate) fn __reduce939< + pub(crate) fn __reduce942< >( source_code: &str, mode: Mode, @@ -32170,7 +32316,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithStatement = "async", "with", WithItems, ":", Suite => ActionFn(960); + // WithStatement = "async", "with", WithItems, ":", Suite => ActionFn(963); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); @@ -32179,11 +32325,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action960::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + let __nt = super::__action963::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (5, 290) + (5, 291) } - pub(crate) fn __reduce940< + pub(crate) fn __reduce943< >( source_code: &str, mode: Mode, @@ -32192,7 +32338,7 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithStatement = "with", WithItems, ":", Suite => ActionFn(961); + // WithStatement = "with", WithItems, ":", Suite => ActionFn(964); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); @@ -32200,11 +32346,11 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action961::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action964::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (4, 290) + (4, 291) } - pub(crate) fn __reduce941< + pub(crate) fn __reduce944< >( source_code: &str, mode: Mode, @@ -32213,18 +32359,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // XorExpression<"all"> = XorExpression<"all">, "^", AndExpression<"all"> => ActionFn(1523); + // XorExpression<"all"> = XorExpression<"all">, "^", AndExpression<"all"> => ActionFn(1527); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1523::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1527::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 291) + (3, 292) } - pub(crate) fn __reduce942< + pub(crate) fn __reduce945< >( source_code: &str, mode: Mode, @@ -32233,15 +32379,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // XorExpression<"all"> = AndExpression<"all"> => ActionFn(425); + // XorExpression<"all"> = AndExpression<"all"> => ActionFn(428); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action425::<>(source_code, mode, __sym0); + let __nt = super::__action428::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 291) + (1, 292) } - pub(crate) fn __reduce943< + pub(crate) fn __reduce946< >( source_code: &str, mode: Mode, @@ -32250,18 +32396,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // XorExpression<"no-withitems"> = XorExpression<"all">, "^", AndExpression<"all"> => ActionFn(1524); + // XorExpression<"no-withitems"> = XorExpression<"all">, "^", AndExpression<"all"> => ActionFn(1528); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1524::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1528::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 292) + (3, 293) } - pub(crate) fn __reduce944< + pub(crate) fn __reduce947< >( source_code: &str, mode: Mode, @@ -32270,15 +32416,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // XorExpression<"no-withitems"> = AndExpression<"no-withitems"> => ActionFn(532); + // XorExpression<"no-withitems"> = AndExpression<"no-withitems"> => ActionFn(535); let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action532::<>(source_code, mode, __sym0); + let __nt = super::__action535::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 292) + (1, 293) } - pub(crate) fn __reduce945< + pub(crate) fn __reduce948< >( source_code: &str, mode: Mode, @@ -32287,17 +32433,17 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // YieldExpr = "yield", GenericList => ActionFn(1750); + // YieldExpr = "yield", GenericList => ActionFn(1754); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1750::<>(source_code, mode, __sym0, __sym1); + let __nt = super::__action1754::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 293) + (2, 294) } - pub(crate) fn __reduce946< + pub(crate) fn __reduce949< >( source_code: &str, mode: Mode, @@ -32306,15 +32452,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // YieldExpr = "yield" => ActionFn(1751); + // YieldExpr = "yield" => ActionFn(1755); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1751::<>(source_code, mode, __sym0); + let __nt = super::__action1755::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 293) + (1, 294) } - pub(crate) fn __reduce947< + pub(crate) fn __reduce950< >( source_code: &str, mode: Mode, @@ -32323,18 +32469,18 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // YieldExpr = "yield", "from", Test<"all"> => ActionFn(1526); + // YieldExpr = "yield", "from", Test<"all"> => ActionFn(1530); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1526::<>(source_code, mode, __sym0, __sym1, __sym2); + let __nt = super::__action1530::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 293) + (3, 294) } - pub(crate) fn __reduce949< + pub(crate) fn __reduce952< >( source_code: &str, mode: Mode, @@ -32343,15 +32489,15 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // fstring_middle? = fstring_middle => ActionFn(276); + // fstring_middle? = fstring_middle => ActionFn(281); let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action276::<>(source_code, mode, __sym0); - __symbols.push((__start, __Symbol::Variant101(__nt), __end)); - (1, 295) + let __nt = super::__action281::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant104(__nt), __end)); + (1, 296) } - pub(crate) fn __reduce950< + pub(crate) fn __reduce953< >( source_code: &str, mode: Mode, @@ -32360,12 +32506,12 @@ mod __parse__Top { _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // fstring_middle? = => ActionFn(277); + // fstring_middle? = => ActionFn(282); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action277::<>(source_code, mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant101(__nt), __end)); - (0, 295) + let __nt = super::__action282::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant104(__nt), __end)); + (0, 296) } } pub(crate) use self::__parse__Top::TopParser; @@ -32405,7 +32551,7 @@ fn __action2< mode: Mode, (_, start, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, body, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, body, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, alloc::vec::Vec, TextSize), (_, end, _): (TextSize, TextSize, TextSize), ) -> ast::Mod @@ -32730,7 +32876,7 @@ fn __action25< mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, targets, _): (TextSize, Vec, TextSize), + (_, targets, _): (TextSize, Vec, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Stmt { @@ -32748,8 +32894,8 @@ fn __action26< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, expression, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, suffix, _): (TextSize, alloc::vec::Vec, TextSize), + (_, expression, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, suffix, _): (TextSize, alloc::vec::Vec, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { @@ -32783,9 +32929,9 @@ fn __action27< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, target, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, target, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, op, _): (TextSize, ast::Operator, TextSize), - (_, rhs, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, rhs, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { @@ -32809,10 +32955,10 @@ fn __action28< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, target, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, target, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, annotation, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, rhs, _): (TextSize, core::option::Option, TextSize), + (_, annotation, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, rhs, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { @@ -32838,8 +32984,8 @@ fn __action29< source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { e } @@ -32851,8 +32997,8 @@ fn __action30< source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { e } @@ -32863,8 +33009,8 @@ fn __action31< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -32875,8 +33021,8 @@ fn __action32< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -32887,8 +33033,8 @@ fn __action33< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -32899,8 +33045,8 @@ fn __action34< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -32911,8 +33057,8 @@ fn __action35< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -32923,8 +33069,8 @@ fn __action36< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -32935,8 +33081,8 @@ fn __action37< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -32947,8 +33093,8 @@ fn __action38< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -32959,8 +33105,8 @@ fn __action39< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -33162,7 +33308,7 @@ fn __action55< mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, core::option::Option, TextSize), + (_, value, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Stmt { @@ -33180,7 +33326,7 @@ fn __action56< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, expression, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, expression, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Stmt { @@ -33229,8 +33375,8 @@ fn __action59< mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, exc, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, cause, _): (TextSize, core::option::Option, TextSize), + (_, exc, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, cause, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Stmt { @@ -33470,8 +33616,8 @@ fn __action73< mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, test, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, msg, _): (TextSize, core::option::Option, TextSize), + (_, test, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, msg, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Stmt { @@ -33524,7 +33670,7 @@ fn __action75< (_, location, _): (TextSize, TextSize, TextSize), (_, c, _): (TextSize, (IpyEscapeKind, String), TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { { if mode == Mode::Ipython { @@ -33556,7 +33702,7 @@ fn __action76< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, suffix, _): (TextSize, alloc::vec::Vec, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> @@ -33587,7 +33733,7 @@ fn __action76< _ => { return Err(LexicalError { error: LexicalErrorType::OtherError("only Name, Subscript and Attribute expressions are allowed in help end escape command".to_string()), - location: expr.range().start(), + location: expr.start(), }); } } @@ -33733,7 +33879,7 @@ fn __action85< mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, subject, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, subject, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33768,7 +33914,7 @@ fn __action86< (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, tuple_location, _): (TextSize, TextSize, TextSize), - (_, subject, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, subject, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, tuple_end_location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33811,7 +33957,7 @@ fn __action87< (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, tuple_location, _): (TextSize, TextSize, TextSize), - (_, elts, _): (TextSize, Vec, TextSize), + (_, elts, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), (_, tuple_end_location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33879,7 +34025,7 @@ fn __action89< source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, guard, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, guard, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Expr { { @@ -34237,7 +34383,7 @@ fn __action111< (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::Number, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::Expr::NumberLiteral( ast::ExprNumberLiteral { value, range: (location..end_location).into() } @@ -34250,8 +34396,8 @@ fn __action112< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } @@ -34264,9 +34410,9 @@ fn __action113< mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, operand, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, operand, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::Expr::UnaryOp( ast::ExprUnaryOp { @@ -34284,11 +34430,11 @@ fn __action114< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, op, _): (TextSize, ast::Operator, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -34356,7 +34502,7 @@ fn __action118< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Pattern { @@ -34373,7 +34519,7 @@ fn __action119< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Pattern { @@ -34390,19 +34536,36 @@ fn __action120< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, strings, _): (TextSize, alloc::vec::Vec, TextSize), + (_, string, _): (TextSize, StringType, TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), +) -> ast::Pattern +{ + ast::PatternMatchValue { + value: Box::new(string.into()), + range: (location..end_location).into() + }.into() +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action121< +>( + source_code: &str, + mode: Mode, + (_, location, _): (TextSize, TextSize, TextSize), + (_, strings, _): (TextSize, Vec, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { Ok(ast::PatternMatchValue { - value: Box::new(concatenate_strings(strings, (location..end_location).into())?), + value: Box::new(concatenated_strings(strings, (location..end_location).into())?), range: (location..end_location).into() }.into()) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action121< +fn __action122< >( source_code: &str, mode: Mode, @@ -34420,7 +34583,7 @@ fn __action121< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action122< +fn __action123< >( source_code: &str, mode: Mode, @@ -34436,7 +34599,7 @@ fn __action122< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action123< +fn __action124< >( source_code: &str, mode: Mode, @@ -34457,7 +34620,7 @@ fn __action123< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action124< +fn __action125< >( source_code: &str, mode: Mode, @@ -34478,7 +34641,7 @@ fn __action124< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action125< +fn __action126< >( source_code: &str, mode: Mode, @@ -34495,7 +34658,7 @@ fn __action125< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action126< +fn __action127< >( source_code: &str, mode: Mode, @@ -34507,23 +34670,23 @@ fn __action126< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action127< +fn __action128< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, __0, _): (TextSize, ast::Expr, TextSize), ) -> ast::Expr { - e.into() + __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action128< +fn __action129< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Expr { e.into() @@ -34531,23 +34694,19 @@ fn __action128< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action129< +fn __action130< >( source_code: &str, mode: Mode, - (_, location, _): (TextSize, TextSize, TextSize), - (_, _, _): (TextSize, token::Tok, TextSize), - (_, end_location, _): (TextSize, TextSize, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Expr { - ast::ExprNoneLiteral { - range: (location..end_location).into() - }.into() + e.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action130< +fn __action131< >( source_code: &str, mode: Mode, @@ -34556,15 +34715,14 @@ fn __action130< (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Expr { - ast::ExprBooleanLiteral { - value: true, + ast::ExprNoneLiteral { range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action131< +fn __action132< >( source_code: &str, mode: Mode, @@ -34574,28 +34732,31 @@ fn __action131< ) -> ast::Expr { ast::ExprBooleanLiteral { - value: false, + value: true, range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action132< +fn __action133< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, strings, _): (TextSize, alloc::vec::Vec, TextSize), + (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> +) -> ast::Expr { - Ok(concatenate_strings(strings, (location..end_location).into())?) + ast::ExprBooleanLiteral { + value: false, + range: (location..end_location).into() + }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action133< +fn __action134< >( source_code: &str, mode: Mode, @@ -34609,7 +34770,7 @@ fn __action133< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action134< +fn __action135< >( source_code: &str, mode: Mode, @@ -34631,7 +34792,7 @@ fn __action134< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action135< +fn __action136< >( source_code: &str, mode: Mode, @@ -34658,7 +34819,7 @@ fn __action135< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action136< +fn __action137< >( source_code: &str, mode: Mode, @@ -34683,7 +34844,7 @@ fn __action136< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action137< +fn __action138< >( source_code: &str, mode: Mode, @@ -34713,7 +34874,7 @@ fn __action137< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action138< +fn __action139< >( source_code: &str, mode: Mode, @@ -34733,7 +34894,7 @@ fn __action138< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action139< +fn __action140< >( source_code: &str, mode: Mode, @@ -34754,7 +34915,7 @@ fn __action139< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action140< +fn __action141< >( source_code: &str, mode: Mode, @@ -34775,7 +34936,7 @@ fn __action140< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action141< +fn __action142< >( source_code: &str, mode: Mode, @@ -34800,7 +34961,7 @@ fn __action141< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action142< +fn __action143< >( source_code: &str, mode: Mode, @@ -34823,7 +34984,7 @@ fn __action142< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action143< +fn __action144< >( source_code: &str, mode: Mode, @@ -34846,7 +35007,7 @@ fn __action143< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action144< +fn __action145< >( source_code: &str, mode: Mode, @@ -34867,16 +35028,16 @@ fn __action144< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action145< +fn __action146< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, test, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, test, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, body, _): (TextSize, ast::Suite, TextSize), - (_, s2, _): (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), + (_, s2, _): (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize), (_, s3, _): (TextSize, core::option::Option<(TextSize, ast::Suite)>, TextSize), ) -> ast::Stmt { @@ -34903,13 +35064,13 @@ fn __action145< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action146< +fn __action147< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, test, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, test, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, body, _): (TextSize, ast::Suite, TextSize), (_, s2, _): (TextSize, core::option::Option, TextSize), @@ -34935,16 +35096,16 @@ fn __action146< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action147< +fn __action148< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, is_async, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, target, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, target, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, iter, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, iter, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, body, _): (TextSize, ast::Suite, TextSize), (_, orelse, _): (TextSize, core::option::Option, TextSize), @@ -34965,7 +35126,7 @@ fn __action147< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action148< +fn __action149< >( source_code: &str, mode: Mode, @@ -35003,7 +35164,7 @@ fn __action148< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action149< +fn __action150< >( source_code: &str, mode: Mode, @@ -35041,7 +35202,7 @@ fn __action149< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action150< +fn __action151< >( source_code: &str, mode: Mode, @@ -35071,14 +35232,14 @@ fn __action150< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action151< +fn __action152< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, typ, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, typ, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, body, _): (TextSize, ast::Suite, TextSize), ) -> ast::ExceptHandler @@ -35098,14 +35259,14 @@ fn __action151< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action152< +fn __action153< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, x, _): (TextSize, (ast::ParenthesizedExpr, ast::Identifier), TextSize), + (_, x, _): (TextSize, (crate::parser::ParenthesizedExpr, ast::Identifier), TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, body, _): (TextSize, ast::Suite, TextSize), ) -> ast::ExceptHandler @@ -35125,13 +35286,13 @@ fn __action152< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action153< +fn __action154< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, typ, _): (TextSize, core::option::Option, TextSize), + (_, typ, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, body, _): (TextSize, ast::Suite, TextSize), ) -> ast::ExceptHandler @@ -35151,13 +35312,13 @@ fn __action153< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action154< +fn __action155< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, x, _): (TextSize, (ast::ParenthesizedExpr, ast::Identifier), TextSize), + (_, x, _): (TextSize, (crate::parser::ParenthesizedExpr, ast::Identifier), TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, body, _): (TextSize, ast::Suite, TextSize), ) -> ast::ExceptHandler @@ -35177,7 +35338,7 @@ fn __action154< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action155< +fn __action156< >( source_code: &str, mode: Mode, @@ -35197,7 +35358,7 @@ fn __action155< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action156< +fn __action157< >( source_code: &str, mode: Mode, @@ -35212,7 +35373,7 @@ fn __action156< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action157< +fn __action158< >( source_code: &str, mode: Mode, @@ -35231,7 +35392,7 @@ fn __action157< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action158< +fn __action159< >( source_code: &str, mode: Mode, @@ -35246,7 +35407,7 @@ fn __action158< // ``` // In this case, the `(` and `)` are part of the `with` statement. // The same applies to `yield` and `yield from`. - let item = if matches!(item.context_expr, ast::Expr::NamedExpr(_) | ast::Expr::Yield(_) | ast::Expr::YieldFrom(_)) { + let item = if item.optional_vars.is_none() && matches!(item.context_expr, ast::Expr::NamedExpr(_) | ast::Expr::Yield(_) | ast::Expr::YieldFrom(_)) { ast::WithItem { range: item.range().add_start(TextSize::new(1)).sub_end(TextSize::new(1)), context_expr: item.context_expr, @@ -35261,7 +35422,7 @@ fn __action158< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action159< +fn __action160< >( source_code: &str, mode: Mode, @@ -35276,11 +35437,11 @@ fn __action159< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action160< +fn __action161< >( source_code: &str, mode: Mode, - (_, all, _): (TextSize, Vec, TextSize), + (_, all, _): (TextSize, Vec, TextSize), ) -> Vec { { @@ -35294,14 +35455,14 @@ fn __action160< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action161< +fn __action162< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, context_expr, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, context_expr, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, optional_vars, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, optional_vars, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::WithItem { @@ -35317,7 +35478,7 @@ fn __action161< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action162< +fn __action163< >( source_code: &str, mode: Mode, @@ -35328,7 +35489,7 @@ fn __action162< (_, name, _): (TextSize, ast::Identifier, TextSize), (_, type_params, _): (TextSize, core::option::Option, TextSize), (_, parameters, _): (TextSize, ast::Parameters, TextSize), - (_, returns, _): (TextSize, core::option::Option, TextSize), + (_, returns, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, body, _): (TextSize, ast::Suite, TextSize), ) -> ast::Stmt @@ -35352,7 +35513,7 @@ fn __action162< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action163< +fn __action164< >( source_code: &str, mode: Mode, @@ -35370,7 +35531,7 @@ fn __action163< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action164< +fn __action165< >( source_code: &str, mode: Mode, @@ -35379,7 +35540,7 @@ fn __action164< (_, name, _): (TextSize, ast::Expr, TextSize), (_, type_params, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Stmt { @@ -35397,7 +35558,7 @@ fn __action164< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action165< +fn __action166< >( source_code: &str, mode: Mode, @@ -35424,7 +35585,7 @@ fn __action165< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action166< +fn __action167< >( source_code: &str, mode: Mode, @@ -35441,7 +35602,7 @@ fn __action166< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action167< +fn __action168< >( source_code: &str, mode: Mode, @@ -35455,13 +35616,13 @@ fn __action167< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action168< +fn __action169< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), - (_, annotation, _): (TextSize, core::option::Option, TextSize), + (_, annotation, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::ParameterWithDefault { @@ -35474,13 +35635,13 @@ fn __action168< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action169< +fn __action170< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), - (_, annotation, _): (TextSize, core::option::Option, TextSize), + (_, annotation, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Parameter { @@ -35492,13 +35653,13 @@ fn __action169< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action170< +fn __action171< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), - (_, annotation, _): (TextSize, core::option::Option, TextSize), + (_, annotation, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Parameter { @@ -35510,7 +35671,7 @@ fn __action170< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action171< +fn __action172< >( source_code: &str, mode: Mode, @@ -35541,7 +35702,7 @@ fn __action171< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action172< +fn __action173< >( source_code: &str, mode: Mode, @@ -35563,13 +35724,13 @@ fn __action172< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action173< +fn __action174< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), - (_, bound, _): (TextSize, core::option::Option, TextSize), + (_, bound, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::TypeParam { @@ -35582,7 +35743,7 @@ fn __action173< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action174< +fn __action175< >( source_code: &str, mode: Mode, @@ -35601,7 +35762,7 @@ fn __action174< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action175< +fn __action176< >( source_code: &str, mode: Mode, @@ -35620,13 +35781,13 @@ fn __action175< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action176< +fn __action177< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, expression, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, expression, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), ) -> ast::Decorator @@ -35638,15 +35799,15 @@ fn __action176< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action177< +fn __action178< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, core::option::Option, TextSize), + (_, value, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprYield { value: value.map(ast::Expr::from).map(Box::new), @@ -35656,16 +35817,16 @@ fn __action177< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action178< +fn __action179< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprYieldFrom { value: Box::new(value.into()), @@ -35675,38 +35836,38 @@ fn __action178< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action179< +fn __action180< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action180< +fn __action181< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action181< +fn __action182< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, id, _): (TextSize, ast::Identifier, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprName { id: id.into(), @@ -35717,16 +35878,16 @@ fn __action181< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action182< +fn __action183< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, target, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, target, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { ast::ExprNamedExpr { @@ -35739,7 +35900,7 @@ fn __action182< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action183< +fn __action184< >( source_code: &str, mode: Mode, @@ -35750,9 +35911,9 @@ fn __action183< (_, end_location_args, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, fstring_middle, _): (TextSize, core::option::Option<(String, bool)>, TextSize), - (_, body, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, body, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { { if fstring_middle.is_some() { @@ -35773,7 +35934,7 @@ fn __action183< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action184< +fn __action185< >( source_code: &str, mode: Mode, @@ -35785,7 +35946,7 @@ fn __action184< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action185< +fn __action186< >( source_code: &str, mode: Mode, @@ -35797,7 +35958,7 @@ fn __action185< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action186< +fn __action187< >( source_code: &str, mode: Mode, @@ -35809,7 +35970,7 @@ fn __action186< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action187< +fn __action188< >( source_code: &str, mode: Mode, @@ -35821,7 +35982,7 @@ fn __action187< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action188< +fn __action189< >( source_code: &str, mode: Mode, @@ -35833,7 +35994,7 @@ fn __action188< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action189< +fn __action190< >( source_code: &str, mode: Mode, @@ -35845,7 +36006,7 @@ fn __action189< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action190< +fn __action191< >( source_code: &str, mode: Mode, @@ -35857,7 +36018,7 @@ fn __action190< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action191< +fn __action192< >( source_code: &str, mode: Mode, @@ -35870,7 +36031,7 @@ fn __action191< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action192< +fn __action193< >( source_code: &str, mode: Mode, @@ -35882,7 +36043,7 @@ fn __action192< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action193< +fn __action194< >( source_code: &str, mode: Mode, @@ -35895,7 +36056,7 @@ fn __action193< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action194< +fn __action195< >( source_code: &str, mode: Mode, @@ -35907,7 +36068,7 @@ fn __action194< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action195< +fn __action196< >( source_code: &str, mode: Mode, @@ -35919,7 +36080,7 @@ fn __action195< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action196< +fn __action197< >( source_code: &str, mode: Mode, @@ -35931,7 +36092,7 @@ fn __action196< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action197< +fn __action198< >( source_code: &str, mode: Mode, @@ -35943,7 +36104,7 @@ fn __action197< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action198< +fn __action199< >( source_code: &str, mode: Mode, @@ -35955,7 +36116,7 @@ fn __action198< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action199< +fn __action200< >( source_code: &str, mode: Mode, @@ -35967,7 +36128,7 @@ fn __action199< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action200< +fn __action201< >( source_code: &str, mode: Mode, @@ -35979,7 +36140,7 @@ fn __action200< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action201< +fn __action202< >( source_code: &str, mode: Mode, @@ -35991,7 +36152,7 @@ fn __action201< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action202< +fn __action203< >( source_code: &str, mode: Mode, @@ -36003,7 +36164,7 @@ fn __action202< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action203< +fn __action204< >( source_code: &str, mode: Mode, @@ -36015,7 +36176,7 @@ fn __action203< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action204< +fn __action205< >( source_code: &str, mode: Mode, @@ -36027,7 +36188,7 @@ fn __action204< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action205< +fn __action206< >( source_code: &str, mode: Mode, @@ -36039,27 +36200,27 @@ fn __action205< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action206< +fn __action207< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action207< +fn __action208< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, s1, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, s1, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { ast::ExprTuple { @@ -36072,15 +36233,15 @@ fn __action207< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action208< +fn __action209< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, elts, _): (TextSize, Vec, TextSize), + (_, elts, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let elts = elts.into_iter().map(ast::Expr::from).collect(); @@ -36094,29 +36255,29 @@ fn __action208< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action209< +fn __action210< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action210< +fn __action211< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, lower, _): (TextSize, core::option::Option, TextSize), + (_, lower, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, upper, _): (TextSize, core::option::Option, TextSize), - (_, step, _): (TextSize, core::option::Option>, TextSize), + (_, upper, _): (TextSize, core::option::Option, TextSize), + (_, step, _): (TextSize, core::option::Option>, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let lower = lower.map(ast::Expr::from).map(Box::new); @@ -36130,21 +36291,50 @@ fn __action210< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action211< +fn __action212< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, core::option::Option, TextSize), -) -> Option + (_, e, _): (TextSize, core::option::Option, TextSize), +) -> Option { e } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action212< +fn __action213< +>( + source_code: &str, + mode: Mode, + (_, location, _): (TextSize, TextSize, TextSize), + (_, string, _): (TextSize, StringType, TextSize), +) -> ast::Expr +{ + string.into() +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action214< +>( + source_code: &str, + mode: Mode, + (_, location, _): (TextSize, TextSize, TextSize), + (_, strings, _): (TextSize, Vec, TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), +) -> Result> +{ + { + Ok(concatenated_strings(strings, (location..end_location).into())?) + } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action215< >( source_code: &str, mode: Mode, @@ -36156,7 +36346,7 @@ fn __action212< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action213< +fn __action216< >( source_code: &str, mode: Mode, @@ -36168,37 +36358,37 @@ fn __action213< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action214< +fn __action217< >( source_code: &str, mode: Mode, - (_, start_location, _): (TextSize, TextSize, TextSize), + (_, location, _): (TextSize, TextSize, TextSize), (_, string, _): (TextSize, (String, StringKind, bool), TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { { let (source, kind, triple_quoted) = string; - Ok(parse_string_literal(&source, kind, triple_quoted, start_location)?) + Ok(parse_string_literal(&source, kind, triple_quoted, (location..end_location).into())?) } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action215< +fn __action218< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, values, _): (TextSize, alloc::vec::Vec, TextSize), + (_, elements, _): (TextSize, alloc::vec::Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> StringType { { - StringType::FString(ast::ExprFString { - values, - implicit_concatenated: false, + StringType::FString(ast::FString { + elements, range: (location..end_location).into() }) } @@ -36206,47 +36396,48 @@ fn __action215< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action216< +fn __action219< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::Expr, TextSize), -) -> ast::Expr + (_, __0, _): (TextSize, ast::FStringElement, TextSize), +) -> ast::FStringElement { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action217< +fn __action220< >( source_code: &str, mode: Mode, - (_, start_location, _): (TextSize, TextSize, TextSize), + (_, location, _): (TextSize, TextSize, TextSize), (_, fstring_middle, _): (TextSize, (String, bool), TextSize), -) -> Result> + (_, end_location, _): (TextSize, TextSize, TextSize), +) -> Result> { { let (source, is_raw) = fstring_middle; - Ok(parse_fstring_middle(&source, is_raw, start_location)?) + Ok(parse_fstring_literal_element(&source, is_raw, (location..end_location).into())?) } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action218< +fn __action221< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, debug, _): (TextSize, core::option::Option, TextSize), (_, conversion, _): (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), - (_, format_spec, _): (TextSize, core::option::Option, TextSize), + (_, format_spec, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { { if value.expr.is_lambda_expr() && !value.is_parenthesized() { @@ -36262,65 +36453,61 @@ fn __action218< } else { format_spec.as_ref().map_or_else( || end_location - "}".text_len(), - |spec| spec.range().start() - ":".text_len(), + |spec| spec.start() - ":".text_len(), ) }; ast::DebugText { - leading: source_code[TextRange::new(start_offset, value.range().start())].to_string(), - trailing: source_code[TextRange::new(value.range().end(), end_offset)].to_string(), + leading: source_code[TextRange::new(start_offset, value.start())].to_string(), + trailing: source_code[TextRange::new(value.end(), end_offset)].to_string(), } }); Ok( - ast::ExprFormattedValue { - value: Box::new(value.into()), + ast::FStringElement::Expression(ast::FStringExpressionElement { + expression: Box::new(value.into()), debug_text, conversion: conversion.map_or(ast::ConversionFlag::None, |(_, conversion_flag)| { conversion_flag }), format_spec: format_spec.map(Box::new), range: (location..end_location).into(), - } - .into() + }) ) } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action219< +fn __action222< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, format_spec, _): (TextSize, ast::Expr, TextSize), -) -> ast::Expr + (_, format_spec, _): (TextSize, ast::FStringFormatSpec, TextSize), +) -> ast::FStringFormatSpec { format_spec } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action220< +fn __action223< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, values, _): (TextSize, alloc::vec::Vec, TextSize), + (_, elements, _): (TextSize, alloc::vec::Vec, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::Expr +) -> ast::FStringFormatSpec { - { - ast::ExprFString { - values, - implicit_concatenated: false, - range: (location..end_location).into() - }.into() + ast::FStringFormatSpec { + elements, + range: (location..end_location).into(), } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action221< +fn __action224< >( source_code: &str, mode: Mode, @@ -36346,154 +36533,154 @@ fn __action221< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action222< +fn __action225< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, Vec, TextSize), + (_, e, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), -) -> Vec +) -> Vec { e } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action223< +fn __action226< >( source_code: &str, mode: Mode, - (_, elements, _): (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), + (_, elements, _): (TextSize, Vec<(Option>, crate::parser::ParenthesizedExpr)>, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), -) -> Vec<(Option>, ast::ParenthesizedExpr)> +) -> Vec<(Option>, crate::parser::ParenthesizedExpr)> { elements } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action224< +fn __action227< >( source_code: &str, mode: Mode, - (_, e1, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e1, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e2, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> (ast::ParenthesizedExpr, ast::ParenthesizedExpr) + (_, e2, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr) { (e1, e2) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action225< +fn __action228< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), -) -> (Option>, ast::ParenthesizedExpr) + (_, e, _): (TextSize, (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr), TextSize), +) -> (Option>, crate::parser::ParenthesizedExpr) { (Some(Box::new(e.0)), e.1) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action226< +fn __action229< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> (Option>, ast::ParenthesizedExpr) + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> (Option>, crate::parser::ParenthesizedExpr) { (None, e) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action227< +fn __action230< >( source_code: &str, mode: Mode, - (_, e1, _): (TextSize, Vec, TextSize), + (_, e1, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), -) -> Vec +) -> Vec { e1 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action228< +fn __action231< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action229< +fn __action232< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action230< +fn __action233< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action231< +fn __action234< >( source_code: &str, mode: Mode, - (_, elements, _): (TextSize, Vec, TextSize), + (_, elements, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), -) -> Vec +) -> Vec { elements } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action232< +fn __action235< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action233< +fn __action236< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprStarred { value: Box::new(value.into()), @@ -36504,7 +36691,7 @@ fn __action233< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action234< +fn __action237< >( source_code: &str, mode: Mode, @@ -36516,17 +36703,17 @@ fn __action234< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action235< +fn __action238< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, is_async, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, target, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, target, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, iter, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, ifs, _): (TextSize, alloc::vec::Vec, TextSize), + (_, iter, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, ifs, _): (TextSize, alloc::vec::Vec, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Comprehension { @@ -36545,32 +36732,32 @@ fn __action235< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action236< +fn __action239< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action237< +fn __action240< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, c, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, c, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { c } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action238< +fn __action241< >( source_code: &str, mode: Mode, @@ -36593,12 +36780,12 @@ fn __action238< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action239< +fn __action242< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, elt, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, elt, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, generators, _): (TextSize, core::option::Option>, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) @@ -36620,14 +36807,14 @@ fn __action239< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action240< +fn __action243< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, i, _): (TextSize, ast::Identifier, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { @@ -36636,13 +36823,13 @@ fn __action240< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action241< +fn __action244< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { @@ -36656,13 +36843,13 @@ fn __action241< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action242< +fn __action245< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { @@ -36671,7 +36858,7 @@ fn __action242< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action243< +fn __action246< >( source_code: &str, mode: Mode, @@ -36683,7 +36870,7 @@ fn __action243< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action244< +fn __action247< >( source_code: &str, mode: Mode, @@ -36695,7 +36882,7 @@ fn __action244< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action245< +fn __action248< >( source_code: &str, mode: Mode, @@ -36707,7 +36894,7 @@ fn __action245< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action246< +fn __action249< >( source_code: &str, mode: Mode, @@ -36721,7 +36908,7 @@ fn __action246< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action247< +fn __action250< >( source_code: &str, mode: Mode, @@ -36733,7 +36920,7 @@ fn __action247< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action248< +fn __action251< >( source_code: &str, mode: Mode, @@ -36746,7 +36933,7 @@ fn __action248< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action249< +fn __action252< >( source_code: &str, mode: Mode, @@ -36764,40 +36951,40 @@ fn __action249< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action250< +fn __action253< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> alloc::vec::Vec +) -> alloc::vec::Vec { alloc::vec![] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action251< +fn __action254< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), +) -> alloc::vec::Vec { v } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action252< +fn __action255< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, values, _): (TextSize, alloc::vec::Vec, TextSize), - (_, last, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, values, _): (TextSize, alloc::vec::Vec, TextSize), + (_, last, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let values = values.into_iter().chain(std::iter::once(last)).map(ast::Expr::from).collect(); @@ -36807,19 +36994,19 @@ fn __action252< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action253< +fn __action256< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action254< +fn __action257< >( source_code: &str, mode: Mode, @@ -36831,7 +37018,7 @@ fn __action254< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action255< +fn __action258< >( source_code: &str, mode: Mode, @@ -36844,19 +37031,19 @@ fn __action255< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action256< +fn __action259< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, elts, _): (TextSize, Vec, TextSize), + (_, elts, _): (TextSize, Vec, TextSize), (_, trailing_comma, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { if elts.len() == 1 && trailing_comma.is_none() { - ast::ParenthesizedExpr { + crate::parser::ParenthesizedExpr { expr: elts.into_iter().next().unwrap().into(), range: (location..end_location).into(), } @@ -36869,26 +37056,26 @@ fn __action256< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action257< +fn __action260< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { vec![e] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action258< +fn __action261< >( source_code: &str, mode: Mode, - (_, mut v, _): (TextSize, Vec, TextSize), + (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { { v.push(e); @@ -36898,19 +37085,19 @@ fn __action258< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action259< +fn __action262< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, elts, _): (TextSize, Vec, TextSize), + (_, elts, _): (TextSize, Vec, TextSize), (_, trailing_comma, _): (TextSize, core::option::Option, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { if elts.len() == 1 && trailing_comma.is_none() { - ast::ParenthesizedExpr { + crate::parser::ParenthesizedExpr { expr: elts.into_iter().next().unwrap().into(), range: (location..end_location).into(), } @@ -36923,26 +37110,26 @@ fn __action259< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action260< +fn __action263< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, (Option>, ast::ParenthesizedExpr), TextSize), -) -> Vec<(Option>, ast::ParenthesizedExpr)> + (_, e, _): (TextSize, (Option>, crate::parser::ParenthesizedExpr), TextSize), +) -> Vec<(Option>, crate::parser::ParenthesizedExpr)> { vec![e] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action261< +fn __action264< >( source_code: &str, mode: Mode, - (_, mut v, _): (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), + (_, mut v, _): (TextSize, Vec<(Option>, crate::parser::ParenthesizedExpr)>, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, (Option>, ast::ParenthesizedExpr), TextSize), -) -> Vec<(Option>, ast::ParenthesizedExpr)> + (_, e, _): (TextSize, (Option>, crate::parser::ParenthesizedExpr), TextSize), +) -> Vec<(Option>, crate::parser::ParenthesizedExpr)> { { v.push(e); @@ -36952,26 +37139,26 @@ fn __action261< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action262< +fn __action265< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { vec![e] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action263< +fn __action266< >( source_code: &str, mode: Mode, - (_, mut v, _): (TextSize, Vec, TextSize), + (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { { v.push(e); @@ -36981,32 +37168,32 @@ fn __action263< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action264< +fn __action267< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::Expr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, ast::FStringFormatSpec, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action265< +fn __action268< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action266< +fn __action269< >( source_code: &str, mode: Mode, @@ -37018,7 +37205,7 @@ fn __action266< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action267< +fn __action270< >( source_code: &str, mode: Mode, @@ -37031,7 +37218,7 @@ fn __action267< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action268< +fn __action271< >( source_code: &str, mode: Mode, @@ -37043,7 +37230,7 @@ fn __action268< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action269< +fn __action272< >( source_code: &str, mode: Mode, @@ -37056,78 +37243,107 @@ fn __action269< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action270< +fn __action273< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> alloc::vec::Vec +) -> alloc::vec::Vec { alloc::vec![] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action271< +fn __action274< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), +) -> alloc::vec::Vec { v } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action272< +fn __action275< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, Option, TextSize), -) -> core::option::Option> + (_, e1, _): (TextSize, StringType, TextSize), + (_, e2, _): (TextSize, StringType, TextSize), +) -> Vec +{ + vec![e1, e2] +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action276< +>( + source_code: &str, + mode: Mode, + (_, mut v, _): (TextSize, Vec, TextSize), + (_, e, _): (TextSize, StringType, TextSize), +) -> Vec +{ + { + v.push(e); + v + } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action277< +>( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, Option, TextSize), +) -> core::option::Option> { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action273< +fn __action278< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option> +) -> core::option::Option> { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action274< +fn __action279< >( source_code: &str, mode: Mode, - (_, e1, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e1, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e2, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e2, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { vec![e1, e2] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action275< +fn __action280< >( source_code: &str, mode: Mode, - (_, mut v, _): (TextSize, Vec, TextSize), + (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { { v.push(e); @@ -37137,7 +37353,7 @@ fn __action275< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action276< +fn __action281< >( source_code: &str, mode: Mode, @@ -37149,7 +37365,7 @@ fn __action276< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action277< +fn __action282< >( source_code: &str, mode: Mode, @@ -37162,7 +37378,7 @@ fn __action277< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action278< +fn __action283< >( source_code: &str, mode: Mode, @@ -37174,7 +37390,7 @@ fn __action278< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action279< +fn __action284< >( source_code: &str, mode: Mode, @@ -37187,7 +37403,7 @@ fn __action279< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action280< +fn __action285< >( source_code: &str, mode: Mode, @@ -37218,7 +37434,7 @@ fn __action280< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action281< +fn __action286< >( source_code: &str, mode: Mode, @@ -37251,7 +37467,7 @@ fn __action281< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action282< +fn __action287< >( source_code: &str, mode: Mode, @@ -37276,7 +37492,7 @@ fn __action282< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action283< +fn __action288< >( source_code: &str, mode: Mode, @@ -37300,7 +37516,7 @@ fn __action283< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action284< +fn __action289< >( source_code: &str, mode: Mode, @@ -37312,7 +37528,7 @@ fn __action284< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action285< +fn __action290< >( source_code: &str, mode: Mode, @@ -37329,7 +37545,7 @@ fn __action285< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action286< +fn __action291< >( source_code: &str, mode: Mode, @@ -37341,7 +37557,7 @@ fn __action286< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action287< +fn __action292< >( source_code: &str, mode: Mode, @@ -37354,83 +37570,83 @@ fn __action287< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action288< +fn __action293< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action289< +fn __action294< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action290< +fn __action295< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action291< +fn __action296< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action292< +fn __action297< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action293< +fn __action298< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action294< +fn __action299< >( source_code: &str, mode: Mode, @@ -37442,7 +37658,7 @@ fn __action294< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action295< +fn __action300< >( source_code: &str, mode: Mode, @@ -37455,7 +37671,7 @@ fn __action295< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action296< +fn __action301< >( source_code: &str, mode: Mode, @@ -37467,7 +37683,7 @@ fn __action296< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action297< +fn __action302< >( source_code: &str, mode: Mode, @@ -37498,7 +37714,7 @@ fn __action297< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action298< +fn __action303< >( source_code: &str, mode: Mode, @@ -37531,7 +37747,7 @@ fn __action298< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action299< +fn __action304< >( source_code: &str, mode: Mode, @@ -37556,7 +37772,7 @@ fn __action299< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action300< +fn __action305< >( source_code: &str, mode: Mode, @@ -37580,45 +37796,45 @@ fn __action300< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action301< +fn __action306< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action302< +fn __action307< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action303< +fn __action308< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action304< +fn __action309< >( source_code: &str, mode: Mode, @@ -37630,7 +37846,7 @@ fn __action304< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action305< +fn __action310< >( source_code: &str, mode: Mode, @@ -37643,7 +37859,7 @@ fn __action305< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action306< +fn __action311< >( source_code: &str, mode: Mode, @@ -37656,7 +37872,7 @@ fn __action306< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action307< +fn __action312< >( source_code: &str, mode: Mode, @@ -37668,26 +37884,26 @@ fn __action307< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action308< +fn __action313< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { vec![e] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action309< +fn __action314< >( source_code: &str, mode: Mode, - (_, mut v, _): (TextSize, Vec, TextSize), + (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { { v.push(e); @@ -37697,7 +37913,7 @@ fn __action309< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action310< +fn __action315< >( source_code: &str, mode: Mode, @@ -37709,7 +37925,7 @@ fn __action310< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action311< +fn __action316< >( source_code: &str, mode: Mode, @@ -37722,11 +37938,11 @@ fn __action311< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action312< +fn __action317< >( source_code: &str, mode: Mode, - (_, context_expr, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, context_expr, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::WithItem { { @@ -37740,7 +37956,7 @@ fn __action312< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action313< +fn __action318< >( source_code: &str, mode: Mode, @@ -37752,7 +37968,7 @@ fn __action313< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action314< +fn __action319< >( source_code: &str, mode: Mode, @@ -37765,7 +37981,7 @@ fn __action314< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action315< +fn __action320< >( source_code: &str, mode: Mode, @@ -37777,7 +37993,7 @@ fn __action315< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action316< +fn __action321< >( source_code: &str, mode: Mode, @@ -37790,11 +38006,11 @@ fn __action316< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action317< +fn __action322< >( source_code: &str, mode: Mode, - (_, context_expr, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, context_expr, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::WithItem { { @@ -37808,7 +38024,7 @@ fn __action317< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action318< +fn __action323< >( source_code: &str, mode: Mode, @@ -37820,7 +38036,7 @@ fn __action318< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action319< +fn __action324< >( source_code: &str, mode: Mode, @@ -37832,7 +38048,7 @@ fn __action319< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action320< +fn __action325< >( source_code: &str, mode: Mode, @@ -37845,7 +38061,7 @@ fn __action320< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action321< +fn __action326< >( source_code: &str, mode: Mode, @@ -37858,46 +38074,46 @@ fn __action321< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action322< +fn __action327< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action323< +fn __action328< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action324< +fn __action329< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, __1, _): (TextSize, ast::Identifier, TextSize), -) -> (ast::ParenthesizedExpr, ast::Identifier) +) -> (crate::parser::ParenthesizedExpr, ast::Identifier) { (__0, __1) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action325< +fn __action330< >( source_code: &str, mode: Mode, @@ -37909,7 +38125,7 @@ fn __action325< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action326< +fn __action331< >( source_code: &str, mode: Mode, @@ -37922,7 +38138,7 @@ fn __action326< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action327< +fn __action332< >( source_code: &str, mode: Mode, @@ -37934,7 +38150,7 @@ fn __action327< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action328< +fn __action333< >( source_code: &str, mode: Mode, @@ -37947,7 +38163,7 @@ fn __action328< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action329< +fn __action334< >( source_code: &str, mode: Mode, @@ -37961,7 +38177,7 @@ fn __action329< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action330< +fn __action335< >( source_code: &str, mode: Mode, @@ -37973,7 +38189,7 @@ fn __action330< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action331< +fn __action336< >( source_code: &str, mode: Mode, @@ -37986,7 +38202,7 @@ fn __action331< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action332< +fn __action337< >( source_code: &str, mode: Mode, @@ -37998,7 +38214,7 @@ fn __action332< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action333< +fn __action338< >( source_code: &str, mode: Mode, @@ -38011,7 +38227,7 @@ fn __action333< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action334< +fn __action339< >( source_code: &str, mode: Mode, @@ -38023,7 +38239,7 @@ fn __action334< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action335< +fn __action340< >( source_code: &str, mode: Mode, @@ -38036,7 +38252,7 @@ fn __action335< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action336< +fn __action341< >( source_code: &str, mode: Mode, @@ -38050,7 +38266,7 @@ fn __action336< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action337< +fn __action342< >( source_code: &str, mode: Mode, @@ -38062,7 +38278,7 @@ fn __action337< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action338< +fn __action343< >( source_code: &str, mode: Mode, @@ -38075,7 +38291,7 @@ fn __action338< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action339< +fn __action344< >( source_code: &str, mode: Mode, @@ -38090,48 +38306,48 @@ fn __action339< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action340< +fn __action345< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)> +) -> alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)> { alloc::vec![] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action341< +fn __action346< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), -) -> alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)> + (_, v, _): (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize), +) -> alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)> { v } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action342< +fn __action347< >( source_code: &str, mode: Mode, (_, __0, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, __1, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, __1, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, __2, _): (TextSize, ast::Suite, TextSize), -) -> (TextSize, ast::ParenthesizedExpr, ast::Suite) +) -> (TextSize, crate::parser::ParenthesizedExpr, ast::Suite) { (__0, __1, __2) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action343< +fn __action348< >( source_code: &str, mode: Mode, @@ -38143,7 +38359,7 @@ fn __action343< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action344< +fn __action349< >( source_code: &str, mode: Mode, @@ -38160,7 +38376,7 @@ fn __action344< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action345< +fn __action350< >( source_code: &str, mode: Mode, @@ -38172,7 +38388,7 @@ fn __action345< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action346< +fn __action351< >( source_code: &str, mode: Mode, @@ -38189,7 +38405,7 @@ fn __action346< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action347< +fn __action352< >( source_code: &str, mode: Mode, @@ -38201,7 +38417,7 @@ fn __action347< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action348< +fn __action353< >( source_code: &str, mode: Mode, @@ -38218,57 +38434,36 @@ fn __action348< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action349< ->( - source_code: &str, - mode: Mode, - (_, __0, _): (TextSize, StringType, TextSize), -) -> alloc::vec::Vec -{ - alloc::vec![__0] -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action350< ->( - source_code: &str, - mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), - (_, e, _): (TextSize, StringType, TextSize), -) -> alloc::vec::Vec -{ - { let mut v = v; v.push(e); v } -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action351< +fn __action354< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, StringType, TextSize), -) -> alloc::vec::Vec + (_, e1, _): (TextSize, StringType, TextSize), + (_, e2, _): (TextSize, StringType, TextSize), +) -> Vec { - alloc::vec![__0] + vec![e1, e2] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action352< +fn __action355< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, mut v, _): (TextSize, Vec, TextSize), (_, e, _): (TextSize, StringType, TextSize), -) -> alloc::vec::Vec +) -> Vec { - { let mut v = v; v.push(e); v } + { + v.push(e); + v + } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action353< +fn __action356< >( source_code: &str, mode: Mode, @@ -38286,7 +38481,7 @@ fn __action353< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action354< +fn __action357< >( source_code: &str, mode: Mode, @@ -38298,7 +38493,7 @@ fn __action354< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action355< +fn __action358< >( source_code: &str, mode: Mode, @@ -38311,7 +38506,7 @@ fn __action355< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action356< +fn __action359< >( source_code: &str, mode: Mode, @@ -38324,7 +38519,7 @@ fn __action356< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action357< +fn __action360< >( source_code: &str, mode: Mode, @@ -38338,7 +38533,7 @@ fn __action357< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action358< +fn __action361< >( source_code: &str, mode: Mode, @@ -38355,7 +38550,7 @@ fn __action358< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action359< +fn __action362< >( source_code: &str, mode: Mode, @@ -38369,7 +38564,7 @@ fn __action359< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action360< +fn __action363< >( source_code: &str, mode: Mode, @@ -38386,7 +38581,7 @@ fn __action360< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action361< +fn __action364< >( source_code: &str, mode: Mode, @@ -38398,7 +38593,7 @@ fn __action361< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action362< +fn __action365< >( source_code: &str, mode: Mode, @@ -38411,7 +38606,7 @@ fn __action362< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action363< +fn __action366< >( source_code: &str, mode: Mode, @@ -38423,28 +38618,28 @@ fn __action363< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action364< +fn __action367< >( source_code: &str, mode: Mode, - (_, e1, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e1, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e2, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e2, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { vec![e1, e2] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action365< +fn __action368< >( source_code: &str, mode: Mode, - (_, mut v, _): (TextSize, Vec, TextSize), + (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { { v.push(e); @@ -38454,7 +38649,7 @@ fn __action365< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action366< +fn __action369< >( source_code: &str, mode: Mode, @@ -38466,7 +38661,7 @@ fn __action366< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action367< +fn __action370< >( source_code: &str, mode: Mode, @@ -38479,7 +38674,7 @@ fn __action367< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action368< +fn __action371< >( source_code: &str, mode: Mode, @@ -38491,7 +38686,7 @@ fn __action368< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action369< +fn __action372< >( source_code: &str, mode: Mode, @@ -38504,7 +38699,7 @@ fn __action369< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action370< +fn __action373< >( source_code: &str, mode: Mode, @@ -38516,16 +38711,16 @@ fn __action370< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action371< +fn __action374< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -38537,57 +38732,57 @@ fn __action371< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action372< +fn __action375< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action373< +fn __action376< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action374< +fn __action377< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action375< +fn __action378< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action376< +fn __action379< >( source_code: &str, mode: Mode, @@ -38599,7 +38794,7 @@ fn __action376< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action377< +fn __action380< >( source_code: &str, mode: Mode, @@ -38616,7 +38811,7 @@ fn __action377< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action378< +fn __action381< >( source_code: &str, mode: Mode, @@ -38628,7 +38823,7 @@ fn __action378< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action379< +fn __action382< >( source_code: &str, mode: Mode, @@ -38641,7 +38836,7 @@ fn __action379< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action380< +fn __action383< >( source_code: &str, mode: Mode, @@ -38654,7 +38849,7 @@ fn __action380< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action381< +fn __action384< >( source_code: &str, mode: Mode, @@ -38666,7 +38861,7 @@ fn __action381< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action382< +fn __action385< >( source_code: &str, mode: Mode, @@ -38679,7 +38874,7 @@ fn __action382< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action383< +fn __action386< >( source_code: &str, mode: Mode, @@ -38691,7 +38886,7 @@ fn __action383< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action384< +fn __action387< >( source_code: &str, mode: Mode, @@ -38708,7 +38903,7 @@ fn __action384< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action385< +fn __action388< >( source_code: &str, mode: Mode, @@ -38723,7 +38918,7 @@ fn __action385< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action386< +fn __action389< >( source_code: &str, mode: Mode, @@ -38735,7 +38930,7 @@ fn __action386< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action387< +fn __action390< >( source_code: &str, mode: Mode, @@ -38748,7 +38943,7 @@ fn __action387< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action388< +fn __action391< >( source_code: &str, mode: Mode, @@ -38761,7 +38956,7 @@ fn __action388< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action389< +fn __action392< >( source_code: &str, mode: Mode, @@ -38773,7 +38968,7 @@ fn __action389< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action390< +fn __action393< >( source_code: &str, mode: Mode, @@ -38785,7 +38980,7 @@ fn __action390< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action391< +fn __action394< >( source_code: &str, mode: Mode, @@ -38802,7 +38997,7 @@ fn __action391< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action392< +fn __action395< >( source_code: &str, mode: Mode, @@ -38817,106 +39012,106 @@ fn __action392< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action393< +fn __action396< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action394< +fn __action397< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action395< +fn __action398< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action396< +fn __action399< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action397< +fn __action400< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action398< +fn __action401< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action399< +fn __action402< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option +) -> core::option::Option { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action400< +fn __action403< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, body, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, body, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, test, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, test, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, orelse, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, orelse, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprIfExp { test: Box::new(test.into()), @@ -38928,56 +39123,56 @@ fn __action400< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action401< +fn __action404< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action402< +fn __action405< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action403< +fn __action406< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> alloc::vec::Vec +) -> alloc::vec::Vec { alloc::vec![] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action404< +fn __action407< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), +) -> alloc::vec::Vec { v } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action405< +fn __action408< >( source_code: &str, mode: Mode, @@ -38989,7 +39184,7 @@ fn __action405< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action406< +fn __action409< >( source_code: &str, mode: Mode, @@ -39002,7 +39197,7 @@ fn __action406< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action407< +fn __action410< >( source_code: &str, mode: Mode, @@ -39015,7 +39210,7 @@ fn __action407< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action408< +fn __action411< >( source_code: &str, mode: Mode, @@ -39027,7 +39222,7 @@ fn __action408< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action409< +fn __action412< >( source_code: &str, mode: Mode, @@ -39040,7 +39235,7 @@ fn __action409< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action410< +fn __action413< >( source_code: &str, mode: Mode, @@ -39053,7 +39248,7 @@ fn __action410< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action411< +fn __action414< >( source_code: &str, mode: Mode, @@ -39065,7 +39260,7 @@ fn __action411< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action412< +fn __action415< >( source_code: &str, mode: Mode, @@ -39076,7 +39271,7 @@ fn __action412< } #[allow(unused_variables)] -fn __action413< +fn __action416< >( source_code: &str, mode: Mode, @@ -39088,7 +39283,7 @@ fn __action413< } #[allow(unused_variables)] -fn __action414< +fn __action417< >( source_code: &str, mode: Mode, @@ -39101,7 +39296,7 @@ fn __action414< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action415< +fn __action418< >( source_code: &str, mode: Mode, @@ -39113,7 +39308,7 @@ fn __action415< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action416< +fn __action419< >( source_code: &str, mode: Mode, @@ -39126,7 +39321,7 @@ fn __action416< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action417< +fn __action420< >( source_code: &str, mode: Mode, @@ -39138,7 +39333,7 @@ fn __action417< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action418< +fn __action421< >( source_code: &str, mode: Mode, @@ -39151,32 +39346,32 @@ fn __action418< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action419< +fn __action422< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action420< +fn __action423< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action421< +fn __action424< >( source_code: &str, mode: Mode, @@ -39188,7 +39383,7 @@ fn __action421< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action422< +fn __action425< >( source_code: &str, mode: Mode, @@ -39201,7 +39396,7 @@ fn __action422< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action423< +fn __action426< >( source_code: &str, mode: Mode, @@ -39214,16 +39409,16 @@ fn __action423< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action424< +fn __action427< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -39235,19 +39430,19 @@ fn __action424< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action425< +fn __action428< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action426< +fn __action429< >( source_code: &str, mode: Mode, @@ -39259,7 +39454,7 @@ fn __action426< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action427< +fn __action430< >( source_code: &str, mode: Mode, @@ -39272,7 +39467,7 @@ fn __action427< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action428< +fn __action431< >( source_code: &str, mode: Mode, @@ -39285,7 +39480,7 @@ fn __action428< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action429< +fn __action432< >( source_code: &str, mode: Mode, @@ -39297,43 +39492,43 @@ fn __action429< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action430< +fn __action433< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, (TextSize, ast::ParenthesizedExpr, ast::Suite), TextSize), -) -> alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)> + (_, __0, _): (TextSize, (TextSize, crate::parser::ParenthesizedExpr, ast::Suite), TextSize), +) -> alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)> { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action431< +fn __action434< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), - (_, e, _): (TextSize, (TextSize, ast::ParenthesizedExpr, ast::Suite), TextSize), -) -> alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)> + (_, v, _): (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize), + (_, e, _): (TextSize, (TextSize, crate::parser::ParenthesizedExpr, ast::Suite), TextSize), +) -> alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)> { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action432< +fn __action435< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, body, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, body, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, test, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, test, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, orelse, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, orelse, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprIfExp { test: Box::new(test.into()), @@ -39345,31 +39540,31 @@ fn __action432< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action433< +fn __action436< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action434< +fn __action437< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action435< +fn __action438< >( source_code: &str, mode: Mode, @@ -39381,7 +39576,7 @@ fn __action435< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action436< +fn __action439< >( source_code: &str, mode: Mode, @@ -39394,7 +39589,7 @@ fn __action436< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action437< +fn __action440< >( source_code: &str, mode: Mode, @@ -39407,7 +39602,7 @@ fn __action437< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action438< +fn __action441< >( source_code: &str, mode: Mode, @@ -39422,7 +39617,7 @@ fn __action438< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action439< +fn __action442< >( source_code: &str, mode: Mode, @@ -39434,7 +39629,7 @@ fn __action439< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action440< +fn __action443< >( source_code: &str, mode: Mode, @@ -39447,7 +39642,7 @@ fn __action440< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action441< +fn __action444< >( source_code: &str, mode: Mode, @@ -39460,7 +39655,7 @@ fn __action441< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action442< +fn __action445< >( source_code: &str, mode: Mode, @@ -39488,7 +39683,7 @@ fn __action442< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action443< +fn __action446< >( source_code: &str, mode: Mode, @@ -39502,7 +39697,7 @@ fn __action443< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action444< +fn __action447< >( source_code: &str, mode: Mode, @@ -39519,7 +39714,7 @@ fn __action444< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action445< +fn __action448< >( source_code: &str, mode: Mode, @@ -39532,7 +39727,7 @@ fn __action445< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action446< +fn __action449< >( source_code: &str, mode: Mode, @@ -39547,7 +39742,7 @@ fn __action446< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action447< +fn __action450< >( source_code: &str, mode: Mode, @@ -39559,7 +39754,7 @@ fn __action447< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action448< +fn __action451< >( source_code: &str, mode: Mode, @@ -39572,7 +39767,7 @@ fn __action448< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action449< +fn __action452< >( source_code: &str, mode: Mode, @@ -39585,7 +39780,7 @@ fn __action449< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action450< +fn __action453< >( source_code: &str, mode: Mode, @@ -39613,7 +39808,7 @@ fn __action450< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action451< +fn __action454< >( source_code: &str, mode: Mode, @@ -39627,7 +39822,7 @@ fn __action451< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action452< +fn __action455< >( source_code: &str, mode: Mode, @@ -39644,51 +39839,51 @@ fn __action452< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action453< +fn __action456< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::Expr, TextSize), -) -> alloc::vec::Vec + (_, __0, _): (TextSize, ast::FStringElement, TextSize), +) -> alloc::vec::Vec { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action454< +fn __action457< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), - (_, e, _): (TextSize, ast::Expr, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, ast::FStringElement, TextSize), +) -> alloc::vec::Vec { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action455< +fn __action458< >( source_code: &str, mode: Mode, - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { vec![e] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action456< +fn __action459< >( source_code: &str, mode: Mode, - (_, mut v, _): (TextSize, Vec, TextSize), + (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Vec + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Vec { { v.push(e); @@ -39698,53 +39893,53 @@ fn __action456< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action457< +fn __action460< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action458< +fn __action461< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action459< +fn __action462< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action460< +fn __action463< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, values, _): (TextSize, alloc::vec::Vec, TextSize), - (_, last, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, values, _): (TextSize, alloc::vec::Vec, TextSize), + (_, last, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let values = values.into_iter().chain(std::iter::once(last)).map(ast::Expr::from).collect(); @@ -39754,44 +39949,44 @@ fn __action460< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action461< +fn __action464< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action462< +fn __action465< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action463< +fn __action466< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action464< +fn __action467< >( source_code: &str, mode: Mode, @@ -39803,7 +39998,7 @@ fn __action464< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action465< +fn __action468< >( source_code: &str, mode: Mode, @@ -39816,7 +40011,7 @@ fn __action465< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action466< +fn __action469< >( source_code: &str, mode: Mode, @@ -39829,7 +40024,7 @@ fn __action466< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action467< +fn __action470< >( source_code: &str, mode: Mode, @@ -39841,7 +40036,7 @@ fn __action467< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action468< +fn __action471< >( source_code: &str, mode: Mode, @@ -39854,7 +40049,7 @@ fn __action468< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action469< +fn __action472< >( source_code: &str, mode: Mode, @@ -39866,7 +40061,7 @@ fn __action469< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action470< +fn __action473< >( source_code: &str, mode: Mode, @@ -39879,53 +40074,53 @@ fn __action470< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action471< +fn __action474< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action472< +fn __action475< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action473< +fn __action476< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action474< +fn __action477< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, operand, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, operand, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprUnaryOp { operand: Box::new(operand.into()), @@ -39936,19 +40131,19 @@ fn __action474< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action475< +fn __action478< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action476< +fn __action479< >( source_code: &str, mode: Mode, @@ -39960,7 +40155,7 @@ fn __action476< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action477< +fn __action480< >( source_code: &str, mode: Mode, @@ -39977,7 +40172,7 @@ fn __action477< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action478< +fn __action481< >( source_code: &str, mode: Mode, @@ -39989,7 +40184,7 @@ fn __action478< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action479< +fn __action482< >( source_code: &str, mode: Mode, @@ -40002,7 +40197,7 @@ fn __action479< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action480< +fn __action483< >( source_code: &str, mode: Mode, @@ -40015,7 +40210,7 @@ fn __action480< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action481< +fn __action484< >( source_code: &str, mode: Mode, @@ -40027,7 +40222,7 @@ fn __action481< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action482< +fn __action485< >( source_code: &str, mode: Mode, @@ -40040,7 +40235,7 @@ fn __action482< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action483< +fn __action486< >( source_code: &str, mode: Mode, @@ -40052,13 +40247,13 @@ fn __action483< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action484< +fn __action487< >( source_code: &str, mode: Mode, (_, mut i, _): (TextSize, ast::ParameterWithDefault, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, default, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, default, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::ParameterWithDefault { @@ -40071,7 +40266,7 @@ fn __action484< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action485< +fn __action488< >( source_code: &str, mode: Mode, @@ -40083,7 +40278,7 @@ fn __action485< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action486< +fn __action489< >( source_code: &str, mode: Mode, @@ -40096,7 +40291,7 @@ fn __action486< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action487< +fn __action490< >( source_code: &str, mode: Mode, @@ -40108,7 +40303,7 @@ fn __action487< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action488< +fn __action491< >( source_code: &str, mode: Mode, @@ -40125,7 +40320,7 @@ fn __action488< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action489< +fn __action492< >( source_code: &str, mode: Mode, @@ -40137,7 +40332,7 @@ fn __action489< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action490< +fn __action493< >( source_code: &str, mode: Mode, @@ -40150,7 +40345,7 @@ fn __action490< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action491< +fn __action494< >( source_code: &str, mode: Mode, @@ -40163,7 +40358,7 @@ fn __action491< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action492< +fn __action495< >( source_code: &str, mode: Mode, @@ -40175,7 +40370,7 @@ fn __action492< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action493< +fn __action496< >( source_code: &str, mode: Mode, @@ -40188,7 +40383,7 @@ fn __action493< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action494< +fn __action497< >( source_code: &str, mode: Mode, @@ -40200,13 +40395,13 @@ fn __action494< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action495< +fn __action498< >( source_code: &str, mode: Mode, (_, mut i, _): (TextSize, ast::ParameterWithDefault, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, default, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, default, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::ParameterWithDefault { @@ -40219,7 +40414,7 @@ fn __action495< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action496< +fn __action499< >( source_code: &str, mode: Mode, @@ -40231,7 +40426,7 @@ fn __action496< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action497< +fn __action500< >( source_code: &str, mode: Mode, @@ -40244,7 +40439,7 @@ fn __action497< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action498< +fn __action501< >( source_code: &str, mode: Mode, @@ -40256,7 +40451,7 @@ fn __action498< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action499< +fn __action502< >( source_code: &str, mode: Mode, @@ -40269,15 +40464,15 @@ fn __action499< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action500< +fn __action503< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, values, _): (TextSize, alloc::vec::Vec, TextSize), - (_, last, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, values, _): (TextSize, alloc::vec::Vec, TextSize), + (_, last, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let values = values.into_iter().chain(std::iter::once(last)).map(ast::Expr::from).collect(); @@ -40287,28 +40482,28 @@ fn __action500< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action501< +fn __action504< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action502< +fn __action505< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40320,28 +40515,28 @@ fn __action502< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action503< +fn __action506< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action504< +fn __action507< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, op, _): (TextSize, ast::Operator, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40353,27 +40548,27 @@ fn __action504< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action505< +fn __action508< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action506< +fn __action509< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, values, _): (TextSize, alloc::vec::Vec, TextSize), - (_, last, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, values, _): (TextSize, alloc::vec::Vec, TextSize), + (_, last, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let values = values.into_iter().chain(std::iter::once(last)).map(ast::Expr::from).collect(); @@ -40383,19 +40578,19 @@ fn __action506< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action507< +fn __action510< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action508< +fn __action511< >( source_code: &str, mode: Mode, @@ -40407,7 +40602,7 @@ fn __action508< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action509< +fn __action512< >( source_code: &str, mode: Mode, @@ -40420,7 +40615,7 @@ fn __action509< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action510< +fn __action513< >( source_code: &str, mode: Mode, @@ -40432,7 +40627,7 @@ fn __action510< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action511< +fn __action514< >( source_code: &str, mode: Mode, @@ -40445,15 +40640,15 @@ fn __action511< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action512< +fn __action515< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, comparisons, _): (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, comparisons, _): (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let (ops, comparators) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip(); @@ -40463,65 +40658,65 @@ fn __action512< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action513< +fn __action516< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action514< +fn __action517< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, (ast::CmpOp, ast::ParenthesizedExpr), TextSize), -) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> + (_, __0, _): (TextSize, (ast::CmpOp, crate::parser::ParenthesizedExpr), TextSize), +) -> alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)> { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action515< +fn __action518< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), - (_, e, _): (TextSize, (ast::CmpOp, ast::ParenthesizedExpr), TextSize), -) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> + (_, v, _): (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize), + (_, e, _): (TextSize, (ast::CmpOp, crate::parser::ParenthesizedExpr), TextSize), +) -> alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)> { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action516< +fn __action519< >( source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::CmpOp, TextSize), - (_, __1, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> (ast::CmpOp, ast::ParenthesizedExpr) + (_, __1, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> (ast::CmpOp, crate::parser::ParenthesizedExpr) { (__0, __1) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action517< +fn __action520< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, operand, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, operand, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprUnaryOp { operand: Box::new(operand.into()), @@ -40532,28 +40727,28 @@ fn __action517< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action518< +fn __action521< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action519< +fn __action522< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, op, _): (TextSize, ast::Operator, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40565,28 +40760,28 @@ fn __action519< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action520< +fn __action523< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action521< +fn __action524< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, op, _): (TextSize, ast::Operator, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40598,27 +40793,27 @@ fn __action521< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action522< +fn __action525< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action523< +fn __action526< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, comparisons, _): (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, comparisons, _): (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let (ops, comparators) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip(); @@ -40628,28 +40823,28 @@ fn __action523< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action524< +fn __action527< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action525< +fn __action528< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40661,27 +40856,27 @@ fn __action525< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action526< +fn __action529< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action527< +fn __action530< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, op, _): (TextSize, ast::UnaryOp, TextSize), - (_, operand, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, operand, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprUnaryOp { operand: Box::new(operand.into()), @@ -40692,28 +40887,28 @@ fn __action527< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action528< +fn __action531< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action529< +fn __action532< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40725,28 +40920,28 @@ fn __action529< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action530< +fn __action533< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action531< +fn __action534< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40758,28 +40953,28 @@ fn __action531< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action532< +fn __action535< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action533< +fn __action536< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40791,27 +40986,27 @@ fn __action533< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action534< +fn __action537< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action535< +fn __action538< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { ast::ExprAwait { value: Box::new(value.into()), range: (location..end_location).into() }.into() @@ -40820,39 +41015,39 @@ fn __action535< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action536< +fn __action539< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action537< +fn __action540< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action538< +fn __action541< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, func, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, func, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, arguments, _): (TextSize, ast::Arguments, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprCall { func: Box::new(func.into()), @@ -40863,17 +41058,17 @@ fn __action538< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action539< +fn __action542< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, slice, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, slice, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprSubscript { value: Box::new(value.into()), @@ -40885,16 +41080,16 @@ fn __action539< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action540< +fn __action543< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, attr, _): (TextSize, ast::Identifier, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprAttribute { value: Box::new(value.into()), @@ -40906,16 +41101,16 @@ fn __action540< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action541< +fn __action544< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, op, _): (TextSize, ast::Operator, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40927,28 +41122,28 @@ fn __action541< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action542< +fn __action545< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action543< +fn __action546< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, op, _): (TextSize, ast::Operator, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -40960,40 +41155,38 @@ fn __action543< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action544< +fn __action547< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action545< +fn __action548< >( source_code: &str, mode: Mode, - (_, location, _): (TextSize, TextSize, TextSize), - (_, strings, _): (TextSize, alloc::vec::Vec, TextSize), - (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> + (_, expr, _): (TextSize, ast::Expr, TextSize), +) -> crate::parser::ParenthesizedExpr { - Ok(concatenate_strings(strings, (location..end_location).into())?.into()) + expr.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action546< +fn __action549< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::Number, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprNumberLiteral { value, @@ -41003,14 +41196,14 @@ fn __action546< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action547< +fn __action550< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, id, _): (TextSize, ast::Identifier, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprName { id: id.into(), @@ -41021,16 +41214,16 @@ fn __action547< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action548< +fn __action551< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elts, _): (TextSize, core::option::Option>, TextSize), + (_, elts, _): (TextSize, core::option::Option>, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let elts = elts.into_iter().flatten().map(ast::Expr::from).collect(); @@ -41040,17 +41233,17 @@ fn __action548< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action549< +fn __action552< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elt, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, elt, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, generators, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { ast::ExprListComp { elt: Box::new(elt.into()), generators, range: (location..end_location).into() }.into() @@ -41059,21 +41252,21 @@ fn __action549< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action550< +fn __action553< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elts, _): (TextSize, Vec, TextSize), + (_, elts, _): (TextSize, Vec, TextSize), (_, trailing_comma, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { if elts.len() == 1 && trailing_comma.is_none() { - ast::ParenthesizedExpr { + crate::parser::ParenthesizedExpr { expr: elts.into_iter().next().unwrap().into(), range: (location..end_location).into(), } @@ -41086,19 +41279,19 @@ fn __action550< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action551< +fn __action554< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, left, _): (TextSize, core::option::Option>, TextSize), - (_, mid, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, right, _): (TextSize, alloc::vec::Vec, TextSize), + (_, left, _): (TextSize, core::option::Option>, TextSize), + (_, mid, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, alloc::vec::Vec, TextSize), (_, trailing_comma, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { { if left.is_none() && right.is_empty() && trailing_comma.is_none() { @@ -41108,7 +41301,7 @@ fn __action551< location: mid.start(), })?; } - Ok(ast::ParenthesizedExpr { + Ok(crate::parser::ParenthesizedExpr { expr: mid.into(), range: (location..end_location).into(), }) @@ -41121,7 +41314,7 @@ fn __action551< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action552< +fn __action555< >( source_code: &str, mode: Mode, @@ -41129,7 +41322,7 @@ fn __action552< (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprTuple { elts: Vec::new(), @@ -41140,18 +41333,18 @@ fn __action552< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action553< +fn __action556< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { - ast::ParenthesizedExpr { + crate::parser::ParenthesizedExpr { expr: e.into(), range: (location..end_location).into(), } @@ -41159,17 +41352,17 @@ fn __action553< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action554< +fn __action557< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elt, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, elt, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, generators, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprGeneratorExp { elt: Box::new(elt.into()), @@ -41180,17 +41373,17 @@ fn __action554< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action555< +fn __action558< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { { Err(LexicalError{ @@ -41202,16 +41395,16 @@ fn __action555< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action556< +fn __action559< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), + (_, e, _): (TextSize, core::option::Option>, crate::parser::ParenthesizedExpr)>>, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let (keys, values) = e @@ -41225,17 +41418,17 @@ fn __action556< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action557< +fn __action560< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e1, _): (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), + (_, e1, _): (TextSize, (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr), TextSize), (_, generators, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { ast::ExprDictComp { @@ -41249,16 +41442,16 @@ fn __action557< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action558< +fn __action561< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elts, _): (TextSize, Vec, TextSize), + (_, elts, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let elts = elts.into_iter().map(ast::Expr::from).collect(); @@ -41271,17 +41464,17 @@ fn __action558< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action559< +fn __action562< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elt, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, elt, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, generators, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprSetComp { elt: Box::new(elt.into()), @@ -41292,198 +41485,198 @@ fn __action559< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action560< +fn __action563< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBooleanLiteral { value: true, range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action561< +fn __action564< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBooleanLiteral { value: false, range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action562< +fn __action565< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprNoneLiteral { range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action563< +fn __action566< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprEllipsisLiteral { range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action564< +fn __action567< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), -) -> core::option::Option>, ast::ParenthesizedExpr)>> + (_, __0, _): (TextSize, Vec<(Option>, crate::parser::ParenthesizedExpr)>, TextSize), +) -> core::option::Option>, crate::parser::ParenthesizedExpr)>> { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action565< +fn __action568< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option>, ast::ParenthesizedExpr)>> +) -> core::option::Option>, crate::parser::ParenthesizedExpr)>> { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action566< +fn __action569< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> alloc::vec::Vec +) -> alloc::vec::Vec { alloc::vec![] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action567< +fn __action570< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), +) -> alloc::vec::Vec { v } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action568< +fn __action571< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action569< +fn __action572< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, Vec, TextSize), -) -> core::option::Option> + (_, __0, _): (TextSize, Vec, TextSize), +) -> core::option::Option> { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action570< +fn __action573< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option> +) -> core::option::Option> { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action571< +fn __action574< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, Vec, TextSize), + (_, __0, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), -) -> Vec +) -> Vec { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action572< +fn __action575< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, Vec, TextSize), -) -> core::option::Option> + (_, __0, _): (TextSize, Vec, TextSize), +) -> core::option::Option> { Some(__0) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action573< +fn __action576< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option> +) -> core::option::Option> { None } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action574< +fn __action577< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, op, _): (TextSize, ast::Operator, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -41495,27 +41688,27 @@ fn __action574< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action575< +fn __action578< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action576< +fn __action579< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, op, _): (TextSize, ast::UnaryOp, TextSize), - (_, operand, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, operand, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprUnaryOp { operand: Box::new(operand.into()), @@ -41526,53 +41719,53 @@ fn __action576< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action577< +fn __action580< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action578< +fn __action581< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action579< +fn __action582< >( source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action580< +fn __action583< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, left, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, right, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBinOp { left: Box::new(left.into()), @@ -41584,27 +41777,27 @@ fn __action580< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action581< +fn __action584< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action582< +fn __action585< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { ast::ExprAwait { value: Box::new(value.into()), range: (location..end_location).into() }.into() @@ -41613,39 +41806,39 @@ fn __action582< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action583< +fn __action586< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action584< +fn __action587< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + (_, __0, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { __0 } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action585< +fn __action588< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, func, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, func, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, arguments, _): (TextSize, ast::Arguments, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprCall { func: Box::new(func.into()), @@ -41656,17 +41849,17 @@ fn __action585< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action586< +fn __action589< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, slice, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, slice, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprSubscript { value: Box::new(value.into()), @@ -41678,16 +41871,16 @@ fn __action586< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action587< +fn __action590< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, value, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, attr, _): (TextSize, ast::Identifier, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprAttribute { value: Box::new(value.into()), @@ -41699,28 +41892,26 @@ fn __action587< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action588< +fn __action591< >( source_code: &str, mode: Mode, - (_, location, _): (TextSize, TextSize, TextSize), - (_, strings, _): (TextSize, alloc::vec::Vec, TextSize), - (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> + (_, expr, _): (TextSize, ast::Expr, TextSize), +) -> crate::parser::ParenthesizedExpr { - Ok(concatenate_strings(strings, (location..end_location).into())?.into()) + expr.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action589< +fn __action592< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::Number, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprNumberLiteral { value, @@ -41730,14 +41921,14 @@ fn __action589< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action590< +fn __action593< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, id, _): (TextSize, ast::Identifier, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprName { id: id.into(), @@ -41748,16 +41939,16 @@ fn __action590< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action591< +fn __action594< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elts, _): (TextSize, core::option::Option>, TextSize), + (_, elts, _): (TextSize, core::option::Option>, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let elts = elts.into_iter().flatten().map(ast::Expr::from).collect(); @@ -41767,17 +41958,17 @@ fn __action591< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action592< +fn __action595< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elt, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, elt, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, generators, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { ast::ExprListComp { elt: Box::new(elt.into()), generators, range: (location..end_location).into() }.into() @@ -41786,19 +41977,19 @@ fn __action592< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action593< +fn __action596< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, left, _): (TextSize, core::option::Option>, TextSize), - (_, mid, _): (TextSize, ast::ParenthesizedExpr, TextSize), - (_, right, _): (TextSize, alloc::vec::Vec, TextSize), + (_, left, _): (TextSize, core::option::Option>, TextSize), + (_, mid, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), + (_, right, _): (TextSize, alloc::vec::Vec, TextSize), (_, trailing_comma, _): (TextSize, core::option::Option, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { { if left.is_none() && right.is_empty() && trailing_comma.is_none() { @@ -41808,7 +41999,7 @@ fn __action593< location: mid.start(), })?; } - Ok(ast::ParenthesizedExpr { + Ok(crate::parser::ParenthesizedExpr { expr: mid.into(), range: (location..end_location).into(), }) @@ -41821,7 +42012,7 @@ fn __action593< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action594< +fn __action597< >( source_code: &str, mode: Mode, @@ -41829,7 +42020,7 @@ fn __action594< (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprTuple { elts: Vec::new(), @@ -41840,18 +42031,18 @@ fn __action594< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action595< +fn __action598< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { - ast::ParenthesizedExpr { + crate::parser::ParenthesizedExpr { expr: e.into(), range: (location..end_location).into(), } @@ -41859,17 +42050,17 @@ fn __action595< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action596< +fn __action599< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elt, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, elt, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, generators, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprGeneratorExp { elt: Box::new(elt.into()), @@ -41880,17 +42071,17 @@ fn __action596< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action597< +fn __action600< >( source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, e, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { { Err(LexicalError{ @@ -41902,16 +42093,16 @@ fn __action597< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action598< +fn __action601< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e, _): (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), + (_, e, _): (TextSize, core::option::Option>, crate::parser::ParenthesizedExpr)>>, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let (keys, values) = e @@ -41925,17 +42116,17 @@ fn __action598< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action599< +fn __action602< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, e1, _): (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), + (_, e1, _): (TextSize, (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr), TextSize), (_, generators, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { ast::ExprDictComp { @@ -41949,16 +42140,16 @@ fn __action599< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action600< +fn __action603< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elts, _): (TextSize, Vec, TextSize), + (_, elts, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { { let elts = elts.into_iter().map(ast::Expr::from).collect(); @@ -41971,17 +42162,17 @@ fn __action600< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action601< +fn __action604< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, elt, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, elt, _): (TextSize, crate::parser::ParenthesizedExpr, TextSize), (_, generators, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprSetComp { elt: Box::new(elt.into()), @@ -41992,83 +42183,83 @@ fn __action601< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action602< +fn __action605< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBooleanLiteral { value: true, range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action603< +fn __action606< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprBooleanLiteral { value: false, range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action604< +fn __action607< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprNoneLiteral { range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action605< +fn __action608< >( source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { ast::ExprEllipsisLiteral { range: (location..end_location).into() }.into() } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action606< +fn __action609< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, Vec, TextSize), + __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action550( + __action553( source_code, mode, __0, @@ -42082,27 +42273,27 @@ fn __action606< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action607< +fn __action610< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, Vec, TextSize), + __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action550( + __action553( source_code, mode, __0, @@ -42116,29 +42307,29 @@ fn __action607< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action608< +fn __action611< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option>, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __2: (TextSize, core::option::Option>, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __5.0; let __end0 = __5.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action551( + __action554( source_code, mode, __0, @@ -42154,29 +42345,29 @@ fn __action608< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action609< +fn __action612< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option>, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __2: (TextSize, core::option::Option>, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __4.2; let __end0 = __5.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action551( + __action554( source_code, mode, __0, @@ -42192,29 +42383,29 @@ fn __action609< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action610< +fn __action613< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option>, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __2: (TextSize, core::option::Option>, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __5.0; let __end0 = __5.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action593( + __action596( source_code, mode, __0, @@ -42230,29 +42421,29 @@ fn __action610< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action611< +fn __action614< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option>, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __2: (TextSize, core::option::Option>, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __4.2; let __end0 = __5.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action593( + __action596( source_code, mode, __0, @@ -42268,23 +42459,23 @@ fn __action611< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action612< +fn __action615< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), + __0: (TextSize, Vec<(Option>, crate::parser::ParenthesizedExpr)>, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> Vec<(Option>, ast::ParenthesizedExpr)> +) -> Vec<(Option>, crate::parser::ParenthesizedExpr)> { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action223( + __action226( source_code, mode, __0, @@ -42294,23 +42485,23 @@ fn __action612< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action613< +fn __action616< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), -) -> Vec<(Option>, ast::ParenthesizedExpr)> + __0: (TextSize, Vec<(Option>, crate::parser::ParenthesizedExpr)>, TextSize), +) -> Vec<(Option>, crate::parser::ParenthesizedExpr)> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action223( + __action226( source_code, mode, __0, @@ -42320,23 +42511,23 @@ fn __action613< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action614< +fn __action617< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> Vec +) -> Vec { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action231( + __action234( source_code, mode, __0, @@ -42346,23 +42537,23 @@ fn __action614< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action615< +fn __action618< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), -) -> Vec + __0: (TextSize, Vec, TextSize), +) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action231( + __action234( source_code, mode, __0, @@ -42372,25 +42563,25 @@ fn __action615< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action616< +fn __action619< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action259( + __action262( source_code, mode, __0, @@ -42402,25 +42593,25 @@ fn __action616< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action617< +fn __action620< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action259( + __action262( source_code, mode, __0, @@ -42432,25 +42623,25 @@ fn __action617< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action618< +fn __action621< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action256( + __action259( source_code, mode, __0, @@ -42462,25 +42653,25 @@ fn __action618< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action619< +fn __action622< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action256( + __action259( source_code, mode, __0, @@ -42492,7 +42683,7 @@ fn __action619< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action620< +fn __action623< >( source_code: &str, mode: Mode, @@ -42506,7 +42697,7 @@ fn __action620< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, @@ -42526,7 +42717,7 @@ fn __action620< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action621< +fn __action624< >( source_code: &str, mode: Mode, @@ -42539,7 +42730,7 @@ fn __action621< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, @@ -42560,23 +42751,23 @@ fn __action621< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action622< +fn __action625< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> Vec +) -> Vec { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action222( + __action225( source_code, mode, __0, @@ -42586,23 +42777,23 @@ fn __action622< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action623< +fn __action626< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), -) -> Vec + __0: (TextSize, Vec, TextSize), +) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action222( + __action225( source_code, mode, __0, @@ -42612,7 +42803,7 @@ fn __action623< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action624< +fn __action627< >( source_code: &str, mode: Mode, @@ -42626,13 +42817,13 @@ fn __action624< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action135( + __action136( source_code, mode, __0, @@ -42646,7 +42837,7 @@ fn __action624< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action625< +fn __action628< >( source_code: &str, mode: Mode, @@ -42659,14 +42850,14 @@ fn __action625< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action135( + __action136( source_code, mode, __0, @@ -42680,7 +42871,7 @@ fn __action625< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action626< +fn __action629< >( source_code: &str, mode: Mode, @@ -42695,13 +42886,13 @@ fn __action626< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action136( + __action137( source_code, mode, __0, @@ -42716,7 +42907,7 @@ fn __action626< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action627< +fn __action630< >( source_code: &str, mode: Mode, @@ -42730,14 +42921,14 @@ fn __action627< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action136( + __action137( source_code, mode, __0, @@ -42752,7 +42943,7 @@ fn __action627< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action628< +fn __action631< >( source_code: &str, mode: Mode, @@ -42769,13 +42960,13 @@ fn __action628< { let __start0 = __6.0; let __end0 = __6.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action137( + __action138( source_code, mode, __0, @@ -42792,7 +42983,7 @@ fn __action628< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action629< +fn __action632< >( source_code: &str, mode: Mode, @@ -42808,14 +42999,14 @@ fn __action629< { let __start0 = __5.2; let __end0 = __6.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action137( + __action138( source_code, mode, __0, @@ -42832,14 +43023,14 @@ fn __action629< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action630< +fn __action633< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, TextSize, TextSize), - __3: (TextSize, Vec, TextSize), + __3: (TextSize, Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), __6: (TextSize, token::Tok, TextSize), @@ -42851,7 +43042,7 @@ fn __action630< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __4, @@ -42876,14 +43067,14 @@ fn __action630< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action631< +fn __action634< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, TextSize, TextSize), - __3: (TextSize, Vec, TextSize), + __3: (TextSize, Vec, TextSize), __4: (TextSize, TextSize, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, token::Tok, TextSize), @@ -42894,7 +43085,7 @@ fn __action631< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, @@ -42920,7 +43111,7 @@ fn __action631< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action632< +fn __action635< >( source_code: &str, mode: Mode, @@ -42933,13 +43124,13 @@ fn __action632< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action297( + __action302( source_code, mode, __0, @@ -42952,7 +43143,7 @@ fn __action632< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action633< +fn __action636< >( source_code: &str, mode: Mode, @@ -42964,14 +43155,14 @@ fn __action633< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action297( + __action302( source_code, mode, __0, @@ -42984,7 +43175,7 @@ fn __action633< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action634< +fn __action637< >( source_code: &str, mode: Mode, @@ -42997,13 +43188,13 @@ fn __action634< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action298( + __action303( source_code, mode, __0, @@ -43016,7 +43207,7 @@ fn __action634< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action635< +fn __action638< >( source_code: &str, mode: Mode, @@ -43028,14 +43219,14 @@ fn __action635< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action298( + __action303( source_code, mode, __0, @@ -43048,7 +43239,7 @@ fn __action635< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action636< +fn __action639< >( source_code: &str, mode: Mode, @@ -43060,13 +43251,13 @@ fn __action636< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action299( + __action304( source_code, mode, __0, @@ -43078,7 +43269,7 @@ fn __action636< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action637< +fn __action640< >( source_code: &str, mode: Mode, @@ -43089,14 +43280,14 @@ fn __action637< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action299( + __action304( source_code, mode, __0, @@ -43108,7 +43299,7 @@ fn __action637< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action638< +fn __action641< >( source_code: &str, mode: Mode, @@ -43120,13 +43311,13 @@ fn __action638< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action300( + __action305( source_code, mode, __0, @@ -43138,7 +43329,7 @@ fn __action638< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action639< +fn __action642< >( source_code: &str, mode: Mode, @@ -43149,14 +43340,14 @@ fn __action639< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action300( + __action305( source_code, mode, __0, @@ -43168,7 +43359,7 @@ fn __action639< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action640< +fn __action643< >( source_code: &str, mode: Mode, @@ -43181,13 +43372,13 @@ fn __action640< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action280( + __action285( source_code, mode, __0, @@ -43200,7 +43391,7 @@ fn __action640< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action641< +fn __action644< >( source_code: &str, mode: Mode, @@ -43212,14 +43403,14 @@ fn __action641< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action280( + __action285( source_code, mode, __0, @@ -43232,7 +43423,7 @@ fn __action641< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action642< +fn __action645< >( source_code: &str, mode: Mode, @@ -43245,13 +43436,13 @@ fn __action642< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action281( + __action286( source_code, mode, __0, @@ -43264,7 +43455,7 @@ fn __action642< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action643< +fn __action646< >( source_code: &str, mode: Mode, @@ -43276,14 +43467,14 @@ fn __action643< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action281( + __action286( source_code, mode, __0, @@ -43296,7 +43487,7 @@ fn __action643< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action644< +fn __action647< >( source_code: &str, mode: Mode, @@ -43308,13 +43499,13 @@ fn __action644< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action282( + __action287( source_code, mode, __0, @@ -43326,7 +43517,7 @@ fn __action644< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action645< +fn __action648< >( source_code: &str, mode: Mode, @@ -43337,14 +43528,14 @@ fn __action645< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action282( + __action287( source_code, mode, __0, @@ -43356,7 +43547,7 @@ fn __action645< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action646< +fn __action649< >( source_code: &str, mode: Mode, @@ -43368,13 +43559,13 @@ fn __action646< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action283( + __action288( source_code, mode, __0, @@ -43386,7 +43577,7 @@ fn __action646< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action647< +fn __action650< >( source_code: &str, mode: Mode, @@ -43397,14 +43588,14 @@ fn __action647< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action283( + __action288( source_code, mode, __0, @@ -43416,7 +43607,7 @@ fn __action647< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action648< +fn __action651< >( source_code: &str, mode: Mode, @@ -43432,13 +43623,13 @@ fn __action648< { let __start0 = __5.0; let __end0 = __5.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action141( + __action142( source_code, mode, __0, @@ -43454,7 +43645,7 @@ fn __action648< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action649< +fn __action652< >( source_code: &str, mode: Mode, @@ -43469,14 +43660,14 @@ fn __action649< { let __start0 = __4.2; let __end0 = __5.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action141( + __action142( source_code, mode, __0, @@ -43492,7 +43683,7 @@ fn __action649< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action650< +fn __action653< >( source_code: &str, mode: Mode, @@ -43506,13 +43697,13 @@ fn __action650< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action142( + __action143( source_code, mode, __0, @@ -43526,7 +43717,7 @@ fn __action650< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action651< +fn __action654< >( source_code: &str, mode: Mode, @@ -43539,14 +43730,14 @@ fn __action651< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action142( + __action143( source_code, mode, __0, @@ -43560,7 +43751,7 @@ fn __action651< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action652< +fn __action655< >( source_code: &str, mode: Mode, @@ -43574,13 +43765,13 @@ fn __action652< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action143( + __action144( source_code, mode, __0, @@ -43594,7 +43785,7 @@ fn __action652< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action653< +fn __action656< >( source_code: &str, mode: Mode, @@ -43607,14 +43798,14 @@ fn __action653< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action143( + __action144( source_code, mode, __0, @@ -43628,7 +43819,7 @@ fn __action653< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action654< +fn __action657< >( source_code: &str, mode: Mode, @@ -43640,7 +43831,7 @@ fn __action654< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, @@ -43658,7 +43849,7 @@ fn __action654< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action655< +fn __action658< >( source_code: &str, mode: Mode, @@ -43669,7 +43860,7 @@ fn __action655< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, @@ -43688,7 +43879,7 @@ fn __action655< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action656< +fn __action659< >( source_code: &str, mode: Mode, @@ -43703,7 +43894,7 @@ fn __action656< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __4, @@ -43724,7 +43915,7 @@ fn __action656< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action657< +fn __action660< >( source_code: &str, mode: Mode, @@ -43738,7 +43929,7 @@ fn __action657< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, @@ -43760,23 +43951,23 @@ fn __action657< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action658< +fn __action661< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> Vec +) -> Vec { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action227( + __action230( source_code, mode, __0, @@ -43786,23 +43977,23 @@ fn __action658< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action659< +fn __action662< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), -) -> Vec + __0: (TextSize, Vec, TextSize), +) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action227( + __action230( source_code, mode, __0, @@ -43812,25 +44003,25 @@ fn __action659< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action660< +fn __action663< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action208( + __action209( source_code, mode, __0, @@ -43842,25 +44033,25 @@ fn __action660< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action661< +fn __action664< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action208( + __action209( source_code, mode, __0, @@ -43872,7 +44063,7 @@ fn __action661< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action662< +fn __action665< >( source_code: &str, mode: Mode, @@ -43886,13 +44077,13 @@ fn __action662< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action172( + __action173( source_code, mode, __0, @@ -43906,7 +44097,7 @@ fn __action662< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action663< +fn __action666< >( source_code: &str, mode: Mode, @@ -43919,14 +44110,14 @@ fn __action663< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action172( + __action173( source_code, mode, __0, @@ -43940,7 +44131,7 @@ fn __action663< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action664< +fn __action667< >( source_code: &str, mode: Mode, @@ -43952,13 +44143,13 @@ fn __action664< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action156( + __action157( source_code, mode, __0, @@ -43970,7 +44161,7 @@ fn __action664< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action665< +fn __action668< >( source_code: &str, mode: Mode, @@ -43981,14 +44172,14 @@ fn __action665< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action156( + __action157( source_code, mode, __0, @@ -44000,7 +44191,7 @@ fn __action665< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action666< +fn __action669< >( source_code: &str, mode: Mode, @@ -44014,13 +44205,13 @@ fn __action666< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action381( + let __temp0 = __action384( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action157( + __action158( source_code, mode, __0, @@ -44034,7 +44225,7 @@ fn __action666< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action667< +fn __action670< >( source_code: &str, mode: Mode, @@ -44047,14 +44238,14 @@ fn __action667< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action382( + let __temp0 = __action385( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action157( + __action158( source_code, mode, __0, @@ -44068,7 +44259,7 @@ fn __action667< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action668< +fn __action671< >( source_code: &str, mode: Mode, @@ -44081,7 +44272,7 @@ fn __action668< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action405( + let __temp0 = __action408( source_code, mode, __3, @@ -44100,7 +44291,7 @@ fn __action668< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action669< +fn __action672< >( source_code: &str, mode: Mode, @@ -44112,7 +44303,7 @@ fn __action669< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action406( + let __temp0 = __action409( source_code, mode, &__start0, @@ -44132,7 +44323,7 @@ fn __action669< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action670< +fn __action673< >( source_code: &str, mode: Mode, @@ -44144,7 +44335,7 @@ fn __action670< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action405( + let __temp0 = __action408( source_code, mode, __2, @@ -44162,7 +44353,7 @@ fn __action670< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action671< +fn __action674< >( source_code: &str, mode: Mode, @@ -44173,7 +44364,7 @@ fn __action671< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action406( + let __temp0 = __action409( source_code, mode, &__start0, @@ -44192,7 +44383,7 @@ fn __action671< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action672< +fn __action675< >( source_code: &str, mode: Mode, @@ -44205,7 +44396,7 @@ fn __action672< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action405( + let __temp0 = __action408( source_code, mode, __3, @@ -44224,7 +44415,7 @@ fn __action672< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action673< +fn __action676< >( source_code: &str, mode: Mode, @@ -44236,7 +44427,7 @@ fn __action673< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action406( + let __temp0 = __action409( source_code, mode, &__start0, @@ -44256,7 +44447,7 @@ fn __action673< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action674< +fn __action677< >( source_code: &str, mode: Mode, @@ -44268,7 +44459,7 @@ fn __action674< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action405( + let __temp0 = __action408( source_code, mode, __2, @@ -44286,7 +44477,7 @@ fn __action674< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action675< +fn __action678< >( source_code: &str, mode: Mode, @@ -44297,7 +44488,7 @@ fn __action675< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action406( + let __temp0 = __action409( source_code, mode, &__start0, @@ -44316,29 +44507,29 @@ fn __action675< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action676< +fn __action679< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), - __5: (TextSize, core::option::Option, TextSize), + __5: (TextSize, core::option::Option, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action268( + let __temp0 = __action271( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action218( + __action221( source_code, mode, __0, @@ -44354,29 +44545,29 @@ fn __action676< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action677< +fn __action680< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), - __4: (TextSize, core::option::Option, TextSize), + __4: (TextSize, core::option::Option, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action269( + let __temp0 = __action272( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action218( + __action221( source_code, mode, __0, @@ -44392,16 +44583,16 @@ fn __action677< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action678< +fn __action681< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, ast::ParenthesizedExpr, TextSize), + __5: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, ast::Suite, TextSize), __8: (TextSize, core::option::Option, TextSize), @@ -44409,13 +44600,13 @@ fn __action678< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action332( + let __temp0 = __action337( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action147( + __action148( source_code, mode, __0, @@ -44432,15 +44623,15 @@ fn __action678< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action679< +fn __action682< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, ast::Suite, TextSize), __7: (TextSize, core::option::Option, TextSize), @@ -44448,14 +44639,14 @@ fn __action679< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action333( + let __temp0 = __action338( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action147( + __action148( source_code, mode, __0, @@ -44472,7 +44663,7 @@ fn __action679< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action680< +fn __action683< >( source_code: &str, mode: Mode, @@ -44483,20 +44674,20 @@ fn __action680< __4: (TextSize, ast::Identifier, TextSize), __5: (TextSize, core::option::Option, TextSize), __6: (TextSize, ast::Parameters, TextSize), - __7: (TextSize, core::option::Option, TextSize), + __7: (TextSize, core::option::Option, TextSize), __8: (TextSize, token::Tok, TextSize), __9: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action332( + let __temp0 = __action337( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action162( + __action163( source_code, mode, __0, @@ -44514,7 +44705,7 @@ fn __action680< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action681< +fn __action684< >( source_code: &str, mode: Mode, @@ -44524,21 +44715,21 @@ fn __action681< __3: (TextSize, ast::Identifier, TextSize), __4: (TextSize, core::option::Option, TextSize), __5: (TextSize, ast::Parameters, TextSize), - __6: (TextSize, core::option::Option, TextSize), + __6: (TextSize, core::option::Option, TextSize), __7: (TextSize, token::Tok, TextSize), __8: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action333( + let __temp0 = __action338( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action162( + __action163( source_code, mode, __0, @@ -44556,29 +44747,29 @@ fn __action681< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action682< +fn __action685< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, ast::ParenthesizedExpr, TextSize), - __6: (TextSize, alloc::vec::Vec, TextSize), + __5: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __6: (TextSize, alloc::vec::Vec, TextSize), __7: (TextSize, TextSize, TextSize), ) -> ast::Comprehension { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action332( + let __temp0 = __action337( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action235( + __action238( source_code, mode, __0, @@ -44594,29 +44785,29 @@ fn __action682< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action683< +fn __action686< >( source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), - __5: (TextSize, alloc::vec::Vec, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __5: (TextSize, alloc::vec::Vec, TextSize), __6: (TextSize, TextSize, TextSize), ) -> ast::Comprehension { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action333( + let __temp0 = __action338( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action235( + __action238( source_code, mode, __0, @@ -44632,7 +44823,7 @@ fn __action683< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action684< +fn __action687< >( source_code: &str, mode: Mode, @@ -44646,13 +44837,13 @@ fn __action684< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action332( + let __temp0 = __action337( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action155( + __action156( source_code, mode, __0, @@ -44666,7 +44857,7 @@ fn __action684< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action685< +fn __action688< >( source_code: &str, mode: Mode, @@ -44679,14 +44870,14 @@ fn __action685< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action333( + let __temp0 = __action338( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action155( + __action156( source_code, mode, __0, @@ -44700,7 +44891,7 @@ fn __action685< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action686< +fn __action689< >( source_code: &str, mode: Mode, @@ -44710,14 +44901,14 @@ fn __action686< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action437( + let __temp0 = __action440( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action489( + __action492( source_code, mode, __temp0, @@ -44726,7 +44917,7 @@ fn __action686< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action687< +fn __action690< >( source_code: &str, mode: Mode, @@ -44740,14 +44931,14 @@ fn __action687< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action437( + let __temp0 = __action440( source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action634( + __action637( source_code, mode, __0, @@ -44760,7 +44951,7 @@ fn __action687< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action688< +fn __action691< >( source_code: &str, mode: Mode, @@ -44773,14 +44964,14 @@ fn __action688< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action437( + let __temp0 = __action440( source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action635( + __action638( source_code, mode, __0, @@ -44792,7 +44983,7 @@ fn __action688< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action689< +fn __action692< >( source_code: &str, mode: Mode, @@ -44806,14 +44997,14 @@ fn __action689< { let __start0 = __4.0; let __end0 = __5.2; - let __temp0 = __action686( + let __temp0 = __action689( source_code, mode, __4, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action442( + __action445( source_code, mode, __0, @@ -44826,7 +45017,7 @@ fn __action689< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action690< +fn __action693< >( source_code: &str, mode: Mode, @@ -44838,14 +45029,14 @@ fn __action690< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action490( + let __temp0 = __action493( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action442( + __action445( source_code, mode, __0, @@ -44858,7 +45049,7 @@ fn __action690< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action691< +fn __action694< >( source_code: &str, mode: Mode, @@ -44868,14 +45059,14 @@ fn __action691< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action445( + let __temp0 = __action448( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action478( + __action481( source_code, mode, __temp0, @@ -44884,7 +45075,7 @@ fn __action691< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action692< +fn __action695< >( source_code: &str, mode: Mode, @@ -44898,14 +45089,14 @@ fn __action692< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action445( + let __temp0 = __action448( source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action642( + __action645( source_code, mode, __0, @@ -44918,7 +45109,7 @@ fn __action692< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action693< +fn __action696< >( source_code: &str, mode: Mode, @@ -44931,14 +45122,14 @@ fn __action693< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action445( + let __temp0 = __action448( source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action643( + __action646( source_code, mode, __0, @@ -44950,7 +45141,7 @@ fn __action693< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action694< +fn __action697< >( source_code: &str, mode: Mode, @@ -44964,14 +45155,14 @@ fn __action694< { let __start0 = __4.0; let __end0 = __5.2; - let __temp0 = __action691( + let __temp0 = __action694( source_code, mode, __4, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action450( + __action453( source_code, mode, __0, @@ -44984,7 +45175,7 @@ fn __action694< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action695< +fn __action698< >( source_code: &str, mode: Mode, @@ -44996,14 +45187,14 @@ fn __action695< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action479( + let __temp0 = __action482( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action450( + __action453( source_code, mode, __0, @@ -45016,7 +45207,7 @@ fn __action695< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action696< +fn __action699< >( source_code: &str, mode: Mode, @@ -45026,14 +45217,14 @@ fn __action696< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action493( + let __temp0 = __action496( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action508( + __action511( source_code, mode, __temp0, @@ -45042,7 +45233,7 @@ fn __action696< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action697< +fn __action700< >( source_code: &str, mode: Mode, @@ -45053,14 +45244,14 @@ fn __action697< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action493( + let __temp0 = __action496( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action509( + __action512( source_code, mode, __0, @@ -45070,7 +45261,7 @@ fn __action697< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action698< +fn __action701< >( source_code: &str, mode: Mode, @@ -45081,14 +45272,14 @@ fn __action698< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action491( + let __temp0 = __action494( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action444( + __action447( source_code, mode, __0, @@ -45100,7 +45291,7 @@ fn __action698< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action699< +fn __action702< >( source_code: &str, mode: Mode, @@ -45112,13 +45303,13 @@ fn __action699< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action492( + let __temp0 = __action495( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action444( + __action447( source_code, mode, __0, @@ -45130,7 +45321,7 @@ fn __action699< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action700< +fn __action703< >( source_code: &str, mode: Mode, @@ -45143,14 +45334,14 @@ fn __action700< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action491( + let __temp0 = __action494( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action689( + __action692( source_code, mode, __0, @@ -45164,7 +45355,7 @@ fn __action700< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action701< +fn __action704< >( source_code: &str, mode: Mode, @@ -45178,13 +45369,13 @@ fn __action701< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action492( + let __temp0 = __action495( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action689( + __action692( source_code, mode, __0, @@ -45198,7 +45389,7 @@ fn __action701< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action702< +fn __action705< >( source_code: &str, mode: Mode, @@ -45209,14 +45400,14 @@ fn __action702< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action491( + let __temp0 = __action494( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action690( + __action693( source_code, mode, __0, @@ -45228,7 +45419,7 @@ fn __action702< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action703< +fn __action706< >( source_code: &str, mode: Mode, @@ -45240,13 +45431,13 @@ fn __action703< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action492( + let __temp0 = __action495( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action690( + __action693( source_code, mode, __0, @@ -45258,7 +45449,7 @@ fn __action703< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action704< +fn __action707< >( source_code: &str, mode: Mode, @@ -45268,14 +45459,14 @@ fn __action704< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action482( + let __temp0 = __action485( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action510( + __action513( source_code, mode, __temp0, @@ -45284,7 +45475,7 @@ fn __action704< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action705< +fn __action708< >( source_code: &str, mode: Mode, @@ -45295,14 +45486,14 @@ fn __action705< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action482( + let __temp0 = __action485( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action511( + __action514( source_code, mode, __0, @@ -45312,7 +45503,7 @@ fn __action705< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action706< +fn __action709< >( source_code: &str, mode: Mode, @@ -45323,14 +45514,14 @@ fn __action706< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action480( + let __temp0 = __action483( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action452( + __action455( source_code, mode, __0, @@ -45342,7 +45533,7 @@ fn __action706< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action707< +fn __action710< >( source_code: &str, mode: Mode, @@ -45354,13 +45545,13 @@ fn __action707< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action481( + let __temp0 = __action484( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action452( + __action455( source_code, mode, __0, @@ -45372,7 +45563,7 @@ fn __action707< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action708< +fn __action711< >( source_code: &str, mode: Mode, @@ -45385,14 +45576,14 @@ fn __action708< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action480( + let __temp0 = __action483( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action694( + __action697( source_code, mode, __0, @@ -45406,7 +45597,7 @@ fn __action708< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action709< +fn __action712< >( source_code: &str, mode: Mode, @@ -45420,13 +45611,13 @@ fn __action709< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action481( + let __temp0 = __action484( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action694( + __action697( source_code, mode, __0, @@ -45440,7 +45631,7 @@ fn __action709< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action710< +fn __action713< >( source_code: &str, mode: Mode, @@ -45451,14 +45642,14 @@ fn __action710< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action480( + let __temp0 = __action483( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action695( + __action698( source_code, mode, __0, @@ -45470,7 +45661,7 @@ fn __action710< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action711< +fn __action714< >( source_code: &str, mode: Mode, @@ -45482,13 +45673,13 @@ fn __action711< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action481( + let __temp0 = __action484( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action695( + __action698( source_code, mode, __0, @@ -45500,7 +45691,7 @@ fn __action711< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action712< +fn __action715< >( source_code: &str, mode: Mode, @@ -45513,13 +45704,13 @@ fn __action712< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action496( + let __temp0 = __action499( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action700( + __action703( source_code, mode, __0, @@ -45532,7 +45723,7 @@ fn __action712< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action713< +fn __action716< >( source_code: &str, mode: Mode, @@ -45544,14 +45735,14 @@ fn __action713< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action497( + let __temp0 = __action500( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action700( + __action703( source_code, mode, __0, @@ -45564,7 +45755,7 @@ fn __action713< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action714< +fn __action717< >( source_code: &str, mode: Mode, @@ -45578,13 +45769,13 @@ fn __action714< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action496( + let __temp0 = __action499( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action701( + __action704( source_code, mode, __0, @@ -45598,7 +45789,7 @@ fn __action714< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action715< +fn __action718< >( source_code: &str, mode: Mode, @@ -45611,14 +45802,14 @@ fn __action715< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action497( + let __temp0 = __action500( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action701( + __action704( source_code, mode, __0, @@ -45632,7 +45823,7 @@ fn __action715< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action716< +fn __action719< >( source_code: &str, mode: Mode, @@ -45643,13 +45834,13 @@ fn __action716< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action496( + let __temp0 = __action499( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action702( + __action705( source_code, mode, __0, @@ -45660,7 +45851,7 @@ fn __action716< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action717< +fn __action720< >( source_code: &str, mode: Mode, @@ -45670,14 +45861,14 @@ fn __action717< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action497( + let __temp0 = __action500( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action702( + __action705( source_code, mode, __0, @@ -45688,7 +45879,7 @@ fn __action717< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action718< +fn __action721< >( source_code: &str, mode: Mode, @@ -45700,13 +45891,13 @@ fn __action718< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action496( + let __temp0 = __action499( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action703( + __action706( source_code, mode, __0, @@ -45718,7 +45909,7 @@ fn __action718< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action719< +fn __action722< >( source_code: &str, mode: Mode, @@ -45729,14 +45920,14 @@ fn __action719< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action497( + let __temp0 = __action500( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action703( + __action706( source_code, mode, __0, @@ -45748,26 +45939,26 @@ fn __action719< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action720< +fn __action723< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), -) -> (TextSize, ast::ParenthesizedExpr, ast::Suite) +) -> (TextSize, crate::parser::ParenthesizedExpr, ast::Suite) { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action342( + __action347( source_code, mode, __temp0, @@ -45780,7 +45971,7 @@ fn __action720< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action721< +fn __action724< >( source_code: &str, mode: Mode, @@ -45791,14 +45982,14 @@ fn __action721< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action339( + __action344( source_code, mode, __temp0, @@ -45810,19 +46001,19 @@ fn __action721< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action722< +fn __action725< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -45842,26 +46033,26 @@ fn __action722< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action723< +fn __action726< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action502( + __action505( source_code, mode, __temp0, @@ -45874,26 +46065,26 @@ fn __action723< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action724< +fn __action727< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action533( + __action536( source_code, mode, __temp0, @@ -45906,25 +46097,25 @@ fn __action724< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action725< +fn __action728< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action460( + __action463( source_code, mode, __temp0, @@ -45936,25 +46127,25 @@ fn __action725< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action726< +fn __action729< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action506( + __action509( source_code, mode, __temp0, @@ -45966,7 +46157,7 @@ fn __action726< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action727< +fn __action730< >( source_code: &str, mode: Mode, @@ -45978,14 +46169,14 @@ fn __action727< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action238( + __action241( source_code, mode, __temp0, @@ -45998,26 +46189,26 @@ fn __action727< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action728< +fn __action731< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action519( + __action522( source_code, mode, __temp0, @@ -46030,26 +46221,26 @@ fn __action728< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action729< +fn __action732< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action543( + __action546( source_code, mode, __temp0, @@ -46062,7 +46253,7 @@ fn __action729< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action730< +fn __action733< >( source_code: &str, mode: Mode, @@ -46074,7 +46265,7 @@ fn __action730< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -46094,19 +46285,19 @@ fn __action730< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action731< +fn __action734< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, core::option::Option, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, core::option::Option, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -46126,52 +46317,24 @@ fn __action731< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action732< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, TextSize, TextSize), -) -> Result> -{ - let __start0 = __0.0; - let __end0 = __0.0; - let __temp0 = __action414( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action545( - source_code, - mode, - __temp0, - __0, - __1, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action733< +fn __action735< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Number, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action546( + __action549( source_code, mode, __temp0, @@ -46182,24 +46345,24 @@ fn __action733< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action734< +fn __action736< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action547( + __action550( source_code, mode, __temp0, @@ -46210,26 +46373,26 @@ fn __action734< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action735< +fn __action737< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), + __1: (TextSize, core::option::Option>, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action548( + __action551( source_code, mode, __temp0, @@ -46242,27 +46405,27 @@ fn __action735< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action736< +fn __action738< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action549( + __action552( source_code, mode, __temp0, @@ -46276,27 +46439,27 @@ fn __action736< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action737< +fn __action739< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action606( + __action609( source_code, mode, __temp0, @@ -46310,26 +46473,26 @@ fn __action737< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action738< +fn __action740< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action607( + __action610( source_code, mode, __temp0, @@ -46342,29 +46505,29 @@ fn __action738< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action739< +fn __action741< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action608( + __action611( source_code, mode, __temp0, @@ -46380,28 +46543,28 @@ fn __action739< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action740< +fn __action742< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action609( + __action612( source_code, mode, __temp0, @@ -46416,25 +46579,25 @@ fn __action740< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action741< +fn __action743< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action552( + __action555( source_code, mode, __temp0, @@ -46446,26 +46609,26 @@ fn __action741< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action742< +fn __action744< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action553( + __action556( source_code, mode, __temp0, @@ -46478,27 +46641,27 @@ fn __action742< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action743< +fn __action745< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action554( + __action557( source_code, mode, __temp0, @@ -46512,97 +46675,31 @@ fn __action743< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action744< +fn __action746< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action414( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action555( - source_code, - mode, - __0, - __temp0, - __1, - __2, - __3, - __4, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action745< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), - __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr -{ - let __start0 = __0.0; - let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action556( + __action558( source_code, mode, - __temp0, __0, - __1, - __2, - __3, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action746< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), - __2: (TextSize, Vec, TextSize), - __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr -{ - let __start0 = __0.0; - let __end0 = __0.0; - let __temp0 = __action414( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action557( - source_code, - mode, __temp0, - __0, __1, __2, __3, @@ -46617,21 +46714,21 @@ fn __action747< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, core::option::Option>, crate::parser::ParenthesizedExpr)>>, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action558( + __action559( source_code, mode, __temp0, @@ -46649,22 +46746,22 @@ fn __action748< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr), TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action559( + __action560( source_code, mode, __temp0, @@ -46683,24 +46780,28 @@ fn __action749< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, Vec, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, TextSize, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action560( + __action561( source_code, mode, __temp0, __0, __1, + __2, + __3, ) } @@ -46711,24 +46812,30 @@ fn __action750< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, Vec, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, TextSize, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action561( + __action562( source_code, mode, __temp0, __0, __1, + __2, + __3, + __4, ) } @@ -46740,18 +46847,18 @@ fn __action751< mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action562( + __action563( source_code, mode, __temp0, @@ -46768,18 +46875,18 @@ fn __action752< mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action563( + __action564( source_code, mode, __temp0, @@ -46794,20 +46901,20 @@ fn __action753< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> Result> +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action588( + __action565( source_code, mode, __temp0, @@ -46822,20 +46929,20 @@ fn __action754< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::Number, TextSize), + __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action589( + __action566( source_code, mode, __temp0, @@ -46850,20 +46957,20 @@ fn __action755< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::Identifier, TextSize), + __0: (TextSize, ast::Number, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action590( + __action592( source_code, mode, __temp0, @@ -46875,25 +46982,53 @@ fn __action755< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] fn __action756< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, ast::Identifier, TextSize), + __1: (TextSize, TextSize, TextSize), +) -> crate::parser::ParenthesizedExpr +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action417( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action593( + source_code, + mode, + __temp0, + __0, + __1, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action757< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), + __1: (TextSize, core::option::Option>, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action591( + __action594( source_code, mode, __temp0, @@ -46906,27 +47041,27 @@ fn __action756< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action757< +fn __action758< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action592( + __action595( source_code, mode, __temp0, @@ -46940,29 +47075,29 @@ fn __action757< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action758< +fn __action759< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action610( + __action613( source_code, mode, __temp0, @@ -46978,28 +47113,28 @@ fn __action758< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action759< +fn __action760< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action611( + __action614( source_code, mode, __temp0, @@ -47014,25 +47149,25 @@ fn __action759< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action760< +fn __action761< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action594( + __action597( source_code, mode, __temp0, @@ -47044,26 +47179,26 @@ fn __action760< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action761< +fn __action762< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action595( + __action598( source_code, mode, __temp0, @@ -47076,27 +47211,27 @@ fn __action761< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action762< +fn __action763< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action596( + __action599( source_code, mode, __temp0, @@ -47110,27 +47245,27 @@ fn __action762< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action763< +fn __action764< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action597( + __action600( source_code, mode, __0, @@ -47144,26 +47279,26 @@ fn __action763< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action764< +fn __action765< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), + __1: (TextSize, core::option::Option>, crate::parser::ParenthesizedExpr)>>, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action598( + __action601( source_code, mode, __temp0, @@ -47176,27 +47311,27 @@ fn __action764< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action765< +fn __action766< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), + __1: (TextSize, (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr), TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action599( + __action602( source_code, mode, __temp0, @@ -47210,26 +47345,26 @@ fn __action765< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action766< +fn __action767< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action600( + __action603( source_code, mode, __temp0, @@ -47242,27 +47377,27 @@ fn __action766< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action767< +fn __action768< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action601( + __action604( source_code, mode, __temp0, @@ -47276,24 +47411,24 @@ fn __action767< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action768< +fn __action769< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action602( + __action605( source_code, mode, __temp0, @@ -47304,24 +47439,24 @@ fn __action768< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action769< +fn __action770< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action603( + __action606( source_code, mode, __temp0, @@ -47332,24 +47467,24 @@ fn __action769< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action770< +fn __action771< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action604( + __action607( source_code, mode, __temp0, @@ -47360,24 +47495,24 @@ fn __action770< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action771< +fn __action772< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action605( + __action608( source_code, mode, __temp0, @@ -47388,25 +47523,25 @@ fn __action771< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action772< +fn __action773< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Arguments, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action538( + __action541( source_code, mode, __temp0, @@ -47418,27 +47553,27 @@ fn __action772< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action773< +fn __action774< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action539( + __action542( source_code, mode, __temp0, @@ -47452,26 +47587,26 @@ fn __action773< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action774< +fn __action775< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, ast::Identifier, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action540( + __action543( source_code, mode, __temp0, @@ -47484,25 +47619,25 @@ fn __action774< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action775< +fn __action776< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Arguments, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action585( + __action588( source_code, mode, __temp0, @@ -47514,27 +47649,27 @@ fn __action775< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action776< +fn __action777< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action586( + __action589( source_code, mode, __temp0, @@ -47548,26 +47683,26 @@ fn __action776< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action777< +fn __action778< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, ast::Identifier, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action587( + __action590( source_code, mode, __temp0, @@ -47580,25 +47715,25 @@ fn __action777< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action778< +fn __action779< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action535( + __action538( source_code, mode, __temp0, @@ -47610,25 +47745,25 @@ fn __action778< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action779< +fn __action780< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action582( + __action585( source_code, mode, __temp0, @@ -47640,7 +47775,7 @@ fn __action779< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action780< +fn __action781< >( source_code: &str, mode: Mode, @@ -47650,14 +47785,14 @@ fn __action780< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action121( + __action122( source_code, mode, __temp0, @@ -47668,7 +47803,7 @@ fn __action780< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action781< +fn __action782< >( source_code: &str, mode: Mode, @@ -47683,14 +47818,14 @@ fn __action781< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action171( + __action172( source_code, mode, __temp0, @@ -47706,7 +47841,7 @@ fn __action781< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action782< +fn __action783< >( source_code: &str, mode: Mode, @@ -47717,14 +47852,14 @@ fn __action782< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action139( + __action140( source_code, mode, __temp0, @@ -47736,7 +47871,7 @@ fn __action782< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action783< +fn __action784< >( source_code: &str, mode: Mode, @@ -47747,14 +47882,14 @@ fn __action783< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action140( + __action141( source_code, mode, __temp0, @@ -47766,25 +47901,25 @@ fn __action783< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action784< +fn __action785< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action512( + __action515( source_code, mode, __temp0, @@ -47796,25 +47931,25 @@ fn __action784< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action785< +fn __action786< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action523( + __action526( source_code, mode, __temp0, @@ -47826,26 +47961,26 @@ fn __action785< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action786< +fn __action787< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), __3: (TextSize, token::Tok, TextSize), ) -> ast::Decorator { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action176( + __action177( source_code, mode, __temp0, @@ -47858,18 +47993,18 @@ fn __action786< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action787< +fn __action788< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -47888,7 +48023,7 @@ fn __action787< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action788< +fn __action789< >( source_code: &str, mode: Mode, @@ -47898,7 +48033,7 @@ fn __action788< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -47916,7 +48051,7 @@ fn __action788< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action789< +fn __action790< >( source_code: &str, mode: Mode, @@ -47927,7 +48062,7 @@ fn __action789< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -47946,63 +48081,31 @@ fn __action789< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action790< +fn __action791< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), - __1: (TextSize, core::option::Option, TextSize), + __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::Parameter { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action170( - source_code, - mode, - __temp0, - __0, - __1, - __2, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action791< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option, TextSize), - __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::Suite, TextSize), -) -> ast::ExceptHandler -{ - let __start0 = __0.0; - let __end0 = __0.0; - let __temp0 = __action414( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action153( + __action171( source_code, mode, __temp0, __0, __1, __2, - __3, ) } @@ -48013,14 +48116,14 @@ fn __action792< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, (ast::ParenthesizedExpr, ast::Identifier), TextSize), + __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), ) -> ast::ExceptHandler { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48045,22 +48148,21 @@ fn __action793< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::Suite, TextSize), + __1: (TextSize, (crate::parser::ParenthesizedExpr, ast::Identifier), TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, ast::Suite, TextSize), ) -> ast::ExceptHandler { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action151( + __action155( source_code, mode, __temp0, @@ -48068,7 +48170,6 @@ fn __action793< __1, __2, __3, - __4, ) } @@ -48080,14 +48181,14 @@ fn __action794< mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, (ast::ParenthesizedExpr, ast::Identifier), TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, ast::Suite, TextSize), ) -> ast::ExceptHandler { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48112,22 +48213,23 @@ fn __action795< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, (crate::parser::ParenthesizedExpr, ast::Identifier), TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, ast::Suite, TextSize), +) -> ast::ExceptHandler { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action371( + __action153( source_code, mode, __temp0, @@ -48135,6 +48237,7 @@ fn __action795< __1, __2, __3, + __4, ) } @@ -48144,22 +48247,22 @@ fn __action796< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action525( + __action374( source_code, mode, __temp0, @@ -48176,14 +48279,46 @@ fn __action797< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, TextSize, TextSize), +) -> crate::parser::ParenthesizedExpr +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action417( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action528( + source_code, + mode, + __temp0, + __0, + __1, + __2, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action798< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), __2: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48202,19 +48337,19 @@ fn __action797< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action798< +fn __action799< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48234,20 +48369,20 @@ fn __action798< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action799< +fn __action800< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, core::option::Option, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48268,7 +48403,7 @@ fn __action799< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action800< +fn __action801< >( source_code: &str, mode: Mode, @@ -48280,21 +48415,21 @@ fn __action800< let __end0 = __0.0; let __start1 = __0.2; let __end1 = __1.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action414( + let __temp1 = __action417( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action221( + __action224( source_code, mode, __temp0, @@ -48306,26 +48441,26 @@ fn __action800< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action801< +fn __action802< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), ) -> StringType { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action215( + __action218( source_code, mode, __temp0, @@ -48338,24 +48473,24 @@ fn __action801< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action802< +fn __action803< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::Expr +) -> ast::FStringFormatSpec { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action220( + __action223( source_code, mode, __temp0, @@ -48366,55 +48501,57 @@ fn __action802< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action803< +fn __action804< >( source_code: &str, mode: Mode, __0: (TextSize, (String, bool), TextSize), -) -> Result> + __1: (TextSize, TextSize, TextSize), +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action217( + __action220( source_code, mode, __temp0, __0, + __1, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action804< +fn __action805< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), - __4: (TextSize, core::option::Option, TextSize), + __4: (TextSize, core::option::Option, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action676( + __action679( source_code, mode, __temp0, @@ -48430,28 +48567,28 @@ fn __action804< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action805< +fn __action806< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), - __3: (TextSize, core::option::Option, TextSize), + __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action677( + __action680( source_code, mode, __temp0, @@ -48466,25 +48603,25 @@ fn __action805< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action806< +fn __action807< >( source_code: &str, mode: Mode, __0: (TextSize, ast::UnaryOp, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action527( + __action530( source_code, mode, __temp0, @@ -48496,25 +48633,25 @@ fn __action806< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action807< +fn __action808< >( source_code: &str, mode: Mode, __0: (TextSize, ast::UnaryOp, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action576( + __action579( source_code, mode, __temp0, @@ -48526,7 +48663,7 @@ fn __action807< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action808< +fn __action809< >( source_code: &str, mode: Mode, @@ -48536,7 +48673,7 @@ fn __action808< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48554,7 +48691,7 @@ fn __action808< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action809< +fn __action810< >( source_code: &str, mode: Mode, @@ -48564,7 +48701,7 @@ fn __action809< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48582,18 +48719,18 @@ fn __action809< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action810< +fn __action811< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option, TextSize), + __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48612,17 +48749,17 @@ fn __action810< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action811< +fn __action812< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -48640,15 +48777,15 @@ fn __action811< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action812< +fn __action813< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, ast::Suite, TextSize), __7: (TextSize, core::option::Option, TextSize), @@ -48656,14 +48793,14 @@ fn __action812< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action678( + __action681( source_code, mode, __temp0, @@ -48680,14 +48817,14 @@ fn __action812< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action813< +fn __action814< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, ast::Suite, TextSize), __6: (TextSize, core::option::Option, TextSize), @@ -48695,14 +48832,14 @@ fn __action813< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action679( + __action682( source_code, mode, __temp0, @@ -48718,7 +48855,7 @@ fn __action813< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action814< +fn __action815< >( source_code: &str, mode: Mode, @@ -48728,21 +48865,21 @@ fn __action814< __3: (TextSize, ast::Identifier, TextSize), __4: (TextSize, core::option::Option, TextSize), __5: (TextSize, ast::Parameters, TextSize), - __6: (TextSize, core::option::Option, TextSize), + __6: (TextSize, core::option::Option, TextSize), __7: (TextSize, token::Tok, TextSize), __8: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action680( + __action683( source_code, mode, __temp0, @@ -48760,7 +48897,7 @@ fn __action814< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action815< +fn __action816< >( source_code: &str, mode: Mode, @@ -48769,21 +48906,21 @@ fn __action815< __2: (TextSize, ast::Identifier, TextSize), __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, ast::Parameters, TextSize), - __5: (TextSize, core::option::Option, TextSize), + __5: (TextSize, core::option::Option, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action681( + __action684( source_code, mode, __temp0, @@ -48800,25 +48937,25 @@ fn __action815< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action816< +fn __action817< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, core::option::Option>, TextSize), __2: (TextSize, TextSize, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action239( + __action242( source_code, mode, __temp0, @@ -48830,26 +48967,26 @@ fn __action816< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action817< +fn __action818< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action240( + __action243( source_code, mode, __temp0, @@ -48862,25 +48999,25 @@ fn __action817< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action818< +fn __action819< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action241( + __action244( source_code, mode, __temp0, @@ -48892,25 +49029,25 @@ fn __action818< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action819< +fn __action820< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action242( + __action245( source_code, mode, __temp0, @@ -48922,25 +49059,25 @@ fn __action819< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action820< +fn __action821< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action616( + __action619( source_code, mode, __temp0, @@ -48952,24 +49089,24 @@ fn __action820< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action821< +fn __action822< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action617( + __action620( source_code, mode, __temp0, @@ -48980,25 +49117,25 @@ fn __action821< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action822< +fn __action823< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action618( + __action621( source_code, mode, __temp0, @@ -49010,24 +49147,24 @@ fn __action822< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action823< +fn __action824< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action619( + __action622( source_code, mode, __temp0, @@ -49038,7 +49175,7 @@ fn __action823< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action824< +fn __action825< >( source_code: &str, mode: Mode, @@ -49049,7 +49186,7 @@ fn __action824< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49068,7 +49205,7 @@ fn __action824< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action825< +fn __action826< >( source_code: &str, mode: Mode, @@ -49078,14 +49215,14 @@ fn __action825< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action246( + __action249( source_code, mode, __temp0, @@ -49096,28 +49233,28 @@ fn __action825< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action826< +fn __action827< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), - __4: (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), + __4: (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize), __5: (TextSize, core::option::Option<(TextSize, ast::Suite)>, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action145( + __action146( source_code, mode, __temp0, @@ -49132,7 +49269,7 @@ fn __action826< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action827< +fn __action828< >( source_code: &str, mode: Mode, @@ -49143,14 +49280,14 @@ fn __action827< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action392( + __action395( source_code, mode, __temp0, @@ -49162,7 +49299,7 @@ fn __action827< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action828< +fn __action829< >( source_code: &str, mode: Mode, @@ -49173,14 +49310,14 @@ fn __action828< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action385( + __action388( source_code, mode, __temp0, @@ -49192,7 +49329,7 @@ fn __action828< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action829< +fn __action830< >( source_code: &str, mode: Mode, @@ -49202,7 +49339,7 @@ fn __action829< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49220,7 +49357,7 @@ fn __action829< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action830< +fn __action831< >( source_code: &str, mode: Mode, @@ -49233,14 +49370,14 @@ fn __action830< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action620( + __action623( source_code, mode, __temp0, @@ -49254,7 +49391,7 @@ fn __action830< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action831< +fn __action832< >( source_code: &str, mode: Mode, @@ -49266,14 +49403,14 @@ fn __action831< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action621( + __action624( source_code, mode, __temp0, @@ -49286,7 +49423,7 @@ fn __action831< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action832< +fn __action833< >( source_code: &str, mode: Mode, @@ -49296,7 +49433,7 @@ fn __action832< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49314,7 +49451,7 @@ fn __action832< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action833< +fn __action834< >( source_code: &str, mode: Mode, @@ -49325,7 +49462,7 @@ fn __action833< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49344,7 +49481,7 @@ fn __action833< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action834< +fn __action835< >( source_code: &str, mode: Mode, @@ -49357,7 +49494,7 @@ fn __action834< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49378,17 +49515,17 @@ fn __action834< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action835< +fn __action836< >( source_code: &str, mode: Mode, __0: (TextSize, (IpyEscapeKind, String), TextSize), __1: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49406,7 +49543,7 @@ fn __action835< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action836< +fn __action837< >( source_code: &str, mode: Mode, @@ -49416,7 +49553,7 @@ fn __action836< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49434,18 +49571,18 @@ fn __action836< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action837< +fn __action838< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), __2: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49464,7 +49601,7 @@ fn __action837< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action838< +fn __action839< >( source_code: &str, mode: Mode, @@ -49473,29 +49610,29 @@ fn __action838< __2: (TextSize, TextSize, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, core::option::Option<(String, bool)>, TextSize), - __5: (TextSize, ast::ParenthesizedExpr, TextSize), + __5: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; let __start1 = __0.2; let __end1 = __1.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action414( + let __temp1 = __action417( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action183( + __action184( source_code, mode, __temp0, @@ -49512,7 +49649,7 @@ fn __action838< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action839< +fn __action840< >( source_code: &str, mode: Mode, @@ -49522,7 +49659,7 @@ fn __action839< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49540,7 +49677,7 @@ fn __action839< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action840< +fn __action841< >( source_code: &str, mode: Mode, @@ -49550,7 +49687,7 @@ fn __action840< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49568,7 +49705,7 @@ fn __action840< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action841< +fn __action842< >( source_code: &str, mode: Mode, @@ -49578,7 +49715,7 @@ fn __action841< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49596,17 +49733,17 @@ fn __action841< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action842< +fn __action843< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, TextSize, TextSize), ) -> ast::Pattern { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49624,17 +49761,17 @@ fn __action842< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action843< +fn __action844< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, TextSize, TextSize), ) -> ast::Pattern { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49652,17 +49789,17 @@ fn __action843< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action844< +fn __action845< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, StringType, TextSize), __1: (TextSize, TextSize, TextSize), -) -> Result> +) -> ast::Pattern { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -49680,24 +49817,24 @@ fn __action844< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action845< +fn __action846< >( source_code: &str, mode: Mode, - __0: (TextSize, token::Tok, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::Expr +) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action129( + __action121( source_code, mode, __temp0, @@ -49708,7 +49845,7 @@ fn __action845< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action846< +fn __action847< >( source_code: &str, mode: Mode, @@ -49718,14 +49855,14 @@ fn __action846< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action130( + __action131( source_code, mode, __temp0, @@ -49736,7 +49873,7 @@ fn __action846< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action847< +fn __action848< >( source_code: &str, mode: Mode, @@ -49746,14 +49883,14 @@ fn __action847< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action131( + __action132( source_code, mode, __temp0, @@ -49764,24 +49901,24 @@ fn __action847< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action848< +fn __action849< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), -) -> Result> +) -> ast::Expr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action132( + __action133( source_code, mode, __temp0, @@ -49792,7 +49929,7 @@ fn __action848< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action849< +fn __action850< >( source_code: &str, mode: Mode, @@ -49803,14 +49940,14 @@ fn __action849< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action134( + __action135( source_code, mode, __temp0, @@ -49822,7 +49959,7 @@ fn __action849< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action850< +fn __action851< >( source_code: &str, mode: Mode, @@ -49835,14 +49972,14 @@ fn __action850< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action624( + __action627( source_code, mode, __temp0, @@ -49856,7 +49993,7 @@ fn __action850< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action851< +fn __action852< >( source_code: &str, mode: Mode, @@ -49868,14 +50005,14 @@ fn __action851< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action625( + __action628( source_code, mode, __temp0, @@ -49888,7 +50025,7 @@ fn __action851< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action852< +fn __action853< >( source_code: &str, mode: Mode, @@ -49902,14 +50039,14 @@ fn __action852< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action626( + __action629( source_code, mode, __temp0, @@ -49924,7 +50061,7 @@ fn __action852< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action853< +fn __action854< >( source_code: &str, mode: Mode, @@ -49937,14 +50074,14 @@ fn __action853< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action627( + __action630( source_code, mode, __temp0, @@ -49958,7 +50095,7 @@ fn __action853< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action854< +fn __action855< >( source_code: &str, mode: Mode, @@ -49974,14 +50111,14 @@ fn __action854< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action628( + __action631( source_code, mode, __temp0, @@ -49998,7 +50135,7 @@ fn __action854< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action855< +fn __action856< >( source_code: &str, mode: Mode, @@ -50013,14 +50150,14 @@ fn __action855< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action629( + __action632( source_code, mode, __temp0, @@ -50036,7 +50173,7 @@ fn __action855< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action856< +fn __action857< >( source_code: &str, mode: Mode, @@ -50049,7 +50186,7 @@ fn __action856< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -50070,7 +50207,7 @@ fn __action856< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action857< +fn __action858< >( source_code: &str, mode: Mode, @@ -50082,14 +50219,14 @@ fn __action857< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action138( + __action139( source_code, mode, __temp0, @@ -50102,7 +50239,7 @@ fn __action857< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action858< +fn __action859< >( source_code: &str, mode: Mode, @@ -50112,14 +50249,14 @@ fn __action858< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action122( + __action123( source_code, mode, __temp0, @@ -50130,7 +50267,7 @@ fn __action858< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action859< +fn __action860< >( source_code: &str, mode: Mode, @@ -50142,14 +50279,14 @@ fn __action859< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action123( + __action124( source_code, mode, __temp0, @@ -50162,7 +50299,7 @@ fn __action859< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action860< +fn __action861< >( source_code: &str, mode: Mode, @@ -50174,14 +50311,14 @@ fn __action860< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action124( + __action125( source_code, mode, __temp0, @@ -50194,12 +50331,12 @@ fn __action860< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action861< +fn __action862< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -50209,7 +50346,7 @@ fn __action861< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -50232,12 +50369,12 @@ fn __action861< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action862< +fn __action863< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -50251,14 +50388,14 @@ fn __action862< let __end0 = __0.0; let __start1 = __0.2; let __end1 = __1.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action414( + let __temp1 = __action417( source_code, mode, &__start1, @@ -50284,12 +50421,12 @@ fn __action862< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action863< +fn __action864< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -50303,21 +50440,21 @@ fn __action863< let __end0 = __0.0; let __start1 = __0.2; let __end1 = __1.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action414( + let __temp1 = __action417( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action630( + __action633( source_code, mode, __temp0, @@ -50336,12 +50473,12 @@ fn __action863< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action864< +fn __action865< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, TextSize, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -50354,21 +50491,21 @@ fn __action864< let __end0 = __0.0; let __start1 = __0.2; let __end1 = __1.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action414( + let __temp1 = __action417( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action631( + __action634( source_code, mode, __temp0, @@ -50386,26 +50523,26 @@ fn __action864< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action865< +fn __action866< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action182( + __action183( source_code, mode, __temp0, @@ -50418,24 +50555,24 @@ fn __action865< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action866< +fn __action867< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action181( + __action182( source_code, mode, __temp0, @@ -50446,7 +50583,7 @@ fn __action866< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action867< +fn __action868< >( source_code: &str, mode: Mode, @@ -50457,7 +50594,7 @@ fn __action867< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -50476,25 +50613,25 @@ fn __action867< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action868< +fn __action869< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action474( + __action477( source_code, mode, __temp0, @@ -50506,25 +50643,25 @@ fn __action868< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action869< +fn __action870< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action517( + __action520( source_code, mode, __temp0, @@ -50536,17 +50673,17 @@ fn __action869< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action870< +fn __action871< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Number, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -50564,18 +50701,18 @@ fn __action870< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action871< +fn __action872< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -50594,7 +50731,7 @@ fn __action871< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action872< +fn __action873< >( source_code: &str, mode: Mode, @@ -50604,7 +50741,7 @@ fn __action872< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -50622,25 +50759,25 @@ fn __action872< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action873< +fn __action874< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action252( + __action255( source_code, mode, __temp0, @@ -50652,25 +50789,25 @@ fn __action873< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action874< +fn __action875< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action500( + __action503( source_code, mode, __temp0, @@ -50682,7 +50819,7 @@ fn __action874< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action875< +fn __action876< >( source_code: &str, mode: Mode, @@ -50694,14 +50831,14 @@ fn __action875< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action632( + __action635( source_code, mode, __temp0, @@ -50714,7 +50851,7 @@ fn __action875< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action876< +fn __action877< >( source_code: &str, mode: Mode, @@ -50725,14 +50862,14 @@ fn __action876< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action633( + __action636( source_code, mode, __temp0, @@ -50744,7 +50881,7 @@ fn __action876< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action877< +fn __action878< >( source_code: &str, mode: Mode, @@ -50757,14 +50894,14 @@ fn __action877< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action687( + __action690( source_code, mode, __temp0, @@ -50778,7 +50915,7 @@ fn __action877< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action878< +fn __action879< >( source_code: &str, mode: Mode, @@ -50790,14 +50927,14 @@ fn __action878< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action688( + __action691( source_code, mode, __temp0, @@ -50810,7 +50947,7 @@ fn __action878< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action879< +fn __action880< >( source_code: &str, mode: Mode, @@ -50821,14 +50958,14 @@ fn __action879< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action636( + __action639( source_code, mode, __temp0, @@ -50840,7 +50977,7 @@ fn __action879< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action880< +fn __action881< >( source_code: &str, mode: Mode, @@ -50850,14 +50987,14 @@ fn __action880< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action637( + __action640( source_code, mode, __temp0, @@ -50868,7 +51005,7 @@ fn __action880< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action881< +fn __action882< >( source_code: &str, mode: Mode, @@ -50879,14 +51016,14 @@ fn __action881< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action638( + __action641( source_code, mode, __temp0, @@ -50898,7 +51035,7 @@ fn __action881< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action882< +fn __action883< >( source_code: &str, mode: Mode, @@ -50908,14 +51045,14 @@ fn __action882< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action639( + __action642( source_code, mode, __temp0, @@ -50926,7 +51063,7 @@ fn __action882< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action883< +fn __action884< >( source_code: &str, mode: Mode, @@ -50938,14 +51075,14 @@ fn __action883< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action640( + __action643( source_code, mode, __temp0, @@ -50958,7 +51095,7 @@ fn __action883< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action884< +fn __action885< >( source_code: &str, mode: Mode, @@ -50969,14 +51106,14 @@ fn __action884< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action641( + __action644( source_code, mode, __temp0, @@ -50988,7 +51125,7 @@ fn __action884< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action885< +fn __action886< >( source_code: &str, mode: Mode, @@ -51001,14 +51138,14 @@ fn __action885< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action692( + __action695( source_code, mode, __temp0, @@ -51022,7 +51159,7 @@ fn __action885< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action886< +fn __action887< >( source_code: &str, mode: Mode, @@ -51034,14 +51171,14 @@ fn __action886< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action693( + __action696( source_code, mode, __temp0, @@ -51054,7 +51191,7 @@ fn __action886< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action887< +fn __action888< >( source_code: &str, mode: Mode, @@ -51065,14 +51202,14 @@ fn __action887< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action644( + __action647( source_code, mode, __temp0, @@ -51084,7 +51221,7 @@ fn __action887< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action888< +fn __action889< >( source_code: &str, mode: Mode, @@ -51094,14 +51231,14 @@ fn __action888< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action645( + __action648( source_code, mode, __temp0, @@ -51112,7 +51249,7 @@ fn __action888< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action889< +fn __action890< >( source_code: &str, mode: Mode, @@ -51123,14 +51260,14 @@ fn __action889< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action646( + __action649( source_code, mode, __temp0, @@ -51142,7 +51279,7 @@ fn __action889< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action890< +fn __action891< >( source_code: &str, mode: Mode, @@ -51152,14 +51289,14 @@ fn __action890< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action647( + __action650( source_code, mode, __temp0, @@ -51170,7 +51307,7 @@ fn __action890< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action891< +fn __action892< >( source_code: &str, mode: Mode, @@ -51182,14 +51319,14 @@ fn __action891< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action712( + __action715( source_code, mode, __temp0, @@ -51202,7 +51339,7 @@ fn __action891< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action892< +fn __action893< >( source_code: &str, mode: Mode, @@ -51213,14 +51350,14 @@ fn __action892< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action713( + __action716( source_code, mode, __temp0, @@ -51232,7 +51369,7 @@ fn __action892< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action893< +fn __action894< >( source_code: &str, mode: Mode, @@ -51245,14 +51382,14 @@ fn __action893< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action714( + __action717( source_code, mode, __temp0, @@ -51266,7 +51403,7 @@ fn __action893< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action894< +fn __action895< >( source_code: &str, mode: Mode, @@ -51278,14 +51415,14 @@ fn __action894< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action715( + __action718( source_code, mode, __temp0, @@ -51298,7 +51435,7 @@ fn __action894< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action895< +fn __action896< >( source_code: &str, mode: Mode, @@ -51308,14 +51445,14 @@ fn __action895< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action716( + __action719( source_code, mode, __temp0, @@ -51326,7 +51463,7 @@ fn __action895< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action896< +fn __action897< >( source_code: &str, mode: Mode, @@ -51335,14 +51472,14 @@ fn __action896< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action717( + __action720( source_code, mode, __temp0, @@ -51352,7 +51489,7 @@ fn __action896< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action897< +fn __action898< >( source_code: &str, mode: Mode, @@ -51363,14 +51500,14 @@ fn __action897< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action718( + __action721( source_code, mode, __temp0, @@ -51382,7 +51519,7 @@ fn __action897< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action898< +fn __action899< >( source_code: &str, mode: Mode, @@ -51392,14 +51529,14 @@ fn __action898< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action719( + __action722( source_code, mode, __temp0, @@ -51410,7 +51547,7 @@ fn __action898< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action899< +fn __action900< >( source_code: &str, mode: Mode, @@ -51422,14 +51559,14 @@ fn __action899< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action708( + __action711( source_code, mode, __temp0, @@ -51442,7 +51579,7 @@ fn __action899< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action900< +fn __action901< >( source_code: &str, mode: Mode, @@ -51455,14 +51592,14 @@ fn __action900< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action709( + __action712( source_code, mode, __temp0, @@ -51476,7 +51613,7 @@ fn __action900< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action901< +fn __action902< >( source_code: &str, mode: Mode, @@ -51486,14 +51623,14 @@ fn __action901< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action710( + __action713( source_code, mode, __temp0, @@ -51504,7 +51641,7 @@ fn __action901< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action902< +fn __action903< >( source_code: &str, mode: Mode, @@ -51515,14 +51652,14 @@ fn __action902< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action711( + __action714( source_code, mode, __temp0, @@ -51534,7 +51671,7 @@ fn __action902< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action903< +fn __action904< >( source_code: &str, mode: Mode, @@ -51546,14 +51683,14 @@ fn __action903< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action165( + __action166( source_code, mode, __temp0, @@ -51566,7 +51703,7 @@ fn __action903< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action904< +fn __action905< >( source_code: &str, mode: Mode, @@ -51576,7 +51713,7 @@ fn __action904< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -51594,7 +51731,7 @@ fn __action904< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action905< +fn __action906< >( source_code: &str, mode: Mode, @@ -51609,14 +51746,14 @@ fn __action905< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action648( + __action651( source_code, mode, __temp0, @@ -51632,7 +51769,7 @@ fn __action905< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action906< +fn __action907< >( source_code: &str, mode: Mode, @@ -51646,14 +51783,14 @@ fn __action906< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action649( + __action652( source_code, mode, __temp0, @@ -51668,7 +51805,7 @@ fn __action906< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action907< +fn __action908< >( source_code: &str, mode: Mode, @@ -51681,14 +51818,14 @@ fn __action907< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action650( + __action653( source_code, mode, __temp0, @@ -51702,7 +51839,7 @@ fn __action907< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action908< +fn __action909< >( source_code: &str, mode: Mode, @@ -51714,14 +51851,14 @@ fn __action908< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action651( + __action654( source_code, mode, __temp0, @@ -51734,7 +51871,7 @@ fn __action908< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action909< +fn __action910< >( source_code: &str, mode: Mode, @@ -51747,14 +51884,14 @@ fn __action909< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action652( + __action655( source_code, mode, __temp0, @@ -51768,7 +51905,7 @@ fn __action909< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action910< +fn __action911< >( source_code: &str, mode: Mode, @@ -51780,14 +51917,14 @@ fn __action910< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action653( + __action656( source_code, mode, __temp0, @@ -51800,7 +51937,7 @@ fn __action910< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action911< +fn __action912< >( source_code: &str, mode: Mode, @@ -51811,14 +51948,14 @@ fn __action911< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action144( + __action145( source_code, mode, __temp0, @@ -51830,7 +51967,7 @@ fn __action911< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action912< +fn __action913< >( source_code: &str, mode: Mode, @@ -51841,7 +51978,7 @@ fn __action912< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -51860,7 +51997,7 @@ fn __action912< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action913< +fn __action914< >( source_code: &str, mode: Mode, @@ -51871,14 +52008,14 @@ fn __action913< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action654( + __action657( source_code, mode, __temp0, @@ -51890,7 +52027,7 @@ fn __action913< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action914< +fn __action915< >( source_code: &str, mode: Mode, @@ -51900,14 +52037,14 @@ fn __action914< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action655( + __action658( source_code, mode, __temp0, @@ -51918,26 +52055,26 @@ fn __action914< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action915< +fn __action916< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action529( + __action532( source_code, mode, __temp0, @@ -51950,26 +52087,26 @@ fn __action915< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action916< +fn __action917< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action580( + __action583( source_code, mode, __temp0, @@ -51982,7 +52119,7 @@ fn __action916< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action917< +fn __action918< >( source_code: &str, mode: Mode, @@ -51992,7 +52129,7 @@ fn __action917< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52010,19 +52147,19 @@ fn __action917< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action918< +fn __action919< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, core::option::Option, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, core::option::Option, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52042,7 +52179,7 @@ fn __action918< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action919< +fn __action920< >( source_code: &str, mode: Mode, @@ -52054,7 +52191,7 @@ fn __action919< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52074,7 +52211,7 @@ fn __action919< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action920< +fn __action921< >( source_code: &str, mode: Mode, @@ -52085,7 +52222,7 @@ fn __action920< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52104,7 +52241,7 @@ fn __action920< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action921< +fn __action922< >( source_code: &str, mode: Mode, @@ -52117,7 +52254,7 @@ fn __action921< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52138,7 +52275,7 @@ fn __action921< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action922< +fn __action923< >( source_code: &str, mode: Mode, @@ -52152,14 +52289,14 @@ fn __action922< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action656( + __action659( source_code, mode, __temp0, @@ -52174,7 +52311,7 @@ fn __action922< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action923< +fn __action924< >( source_code: &str, mode: Mode, @@ -52187,14 +52324,14 @@ fn __action923< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action657( + __action660( source_code, mode, __temp0, @@ -52208,7 +52345,7 @@ fn __action923< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action924< +fn __action925< >( source_code: &str, mode: Mode, @@ -52220,7 +52357,7 @@ fn __action924< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52238,60 +52375,28 @@ fn __action924< ) } -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action925< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr -{ - let __start0 = __0.0; - let __end0 = __0.0; - let __temp0 = __action414( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action504( - source_code, - mode, - __temp0, - __0, - __1, - __2, - __3, - ) -} - #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] fn __action926< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action541( + __action507( source_code, mode, __temp0, @@ -52305,28 +52410,60 @@ fn __action926< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] fn __action927< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, ast::Operator, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, TextSize, TextSize), +) -> crate::parser::ParenthesizedExpr +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action417( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action544( + source_code, + mode, + __temp0, + __0, + __1, + __2, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action928< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), - __5: (TextSize, alloc::vec::Vec, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __5: (TextSize, alloc::vec::Vec, TextSize), __6: (TextSize, TextSize, TextSize), ) -> ast::Comprehension { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action682( + __action685( source_code, mode, __temp0, @@ -52342,28 +52479,28 @@ fn __action927< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action928< +fn __action929< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, TextSize, TextSize), ) -> ast::Comprehension { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action683( + __action686( source_code, mode, __temp0, @@ -52378,24 +52515,24 @@ fn __action928< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action929< +fn __action930< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option, TextSize), -) -> Option + __1: (TextSize, core::option::Option, TextSize), +) -> Option { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action211( + __action212( source_code, mode, __temp0, @@ -52406,25 +52543,25 @@ fn __action929< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action930< +fn __action931< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action233( + __action236( source_code, mode, __temp0, @@ -52436,7 +52573,7 @@ fn __action930< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action931< +fn __action932< >( source_code: &str, mode: Mode, @@ -52447,7 +52584,7 @@ fn __action931< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52466,25 +52603,25 @@ fn __action931< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action932< +fn __action933< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), - __1: (TextSize, core::option::Option, TextSize), + __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::Parameter { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action169( + __action170( source_code, mode, __temp0, @@ -52496,7 +52633,7 @@ fn __action932< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action933< +fn __action934< >( source_code: &str, mode: Mode, @@ -52506,14 +52643,14 @@ fn __action933< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action167( + __action168( source_code, mode, __temp0, @@ -52524,53 +52661,109 @@ fn __action933< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action934< +fn __action935< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, StringType, TextSize), +) -> ast::Expr +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action417( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action213( + source_code, + mode, + __temp0, + __0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action936< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, Vec, TextSize), + __1: (TextSize, TextSize, TextSize), +) -> Result> +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action417( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action214( + source_code, + mode, + __temp0, + __0, + __1, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action937< >( source_code: &str, mode: Mode, __0: (TextSize, (String, StringKind, bool), TextSize), + __1: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action214( + __action217( source_code, mode, __temp0, __0, + __1, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action935< +fn __action938< >( source_code: &str, mode: Mode, - __0: (TextSize, core::option::Option, TextSize), + __0: (TextSize, core::option::Option, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option, TextSize), - __3: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, core::option::Option, TextSize), + __3: (TextSize, core::option::Option>, TextSize), __4: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action210( + __action211( source_code, mode, __temp0, @@ -52584,25 +52777,25 @@ fn __action935< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action936< +fn __action939< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action207( + __action208( source_code, mode, __temp0, @@ -52614,25 +52807,25 @@ fn __action936< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action937< +fn __action940< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action660( + __action663( source_code, mode, __temp0, @@ -52644,24 +52837,24 @@ fn __action937< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action938< +fn __action941< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action661( + __action664( source_code, mode, __temp0, @@ -52672,26 +52865,26 @@ fn __action938< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action939< +fn __action942< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action521( + __action524( source_code, mode, __temp0, @@ -52704,26 +52897,26 @@ fn __action939< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action940< +fn __action943< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action574( + __action577( source_code, mode, __temp0, @@ -52736,28 +52929,28 @@ fn __action940< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action941< +fn __action944< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action400( + __action403( source_code, mode, __temp0, @@ -52772,28 +52965,28 @@ fn __action941< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action942< +fn __action945< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action432( + __action435( source_code, mode, __temp0, @@ -52808,7 +53001,7 @@ fn __action942< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action943< +fn __action946< >( source_code: &str, mode: Mode, @@ -52819,7 +53012,7 @@ fn __action943< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52838,19 +53031,19 @@ fn __action943< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action944< +fn __action947< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::Mod { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, @@ -52870,7 +53063,7 @@ fn __action944< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action945< +fn __action948< >( source_code: &str, mode: Mode, @@ -52885,14 +53078,14 @@ fn __action945< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action148( + __action149( source_code, mode, __temp0, @@ -52908,7 +53101,7 @@ fn __action945< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action946< +fn __action949< >( source_code: &str, mode: Mode, @@ -52923,14 +53116,14 @@ fn __action946< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action149( + __action150( source_code, mode, __temp0, @@ -52946,7 +53139,7 @@ fn __action946< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action947< +fn __action950< >( source_code: &str, mode: Mode, @@ -52958,14 +53151,14 @@ fn __action947< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action150( + __action151( source_code, mode, __temp0, @@ -52978,7 +53171,7 @@ fn __action947< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action948< +fn __action951< >( source_code: &str, mode: Mode, @@ -52988,14 +53181,14 @@ fn __action948< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action163( + __action164( source_code, mode, __temp0, @@ -53006,7 +53199,7 @@ fn __action948< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action949< +fn __action952< >( source_code: &str, mode: Mode, @@ -53014,20 +53207,20 @@ fn __action949< __1: (TextSize, ast::Expr, TextSize), __2: (TextSize, core::option::Option, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action164( + __action165( source_code, mode, __temp0, @@ -53042,25 +53235,25 @@ fn __action949< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action950< +fn __action953< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), - __1: (TextSize, core::option::Option, TextSize), + __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::TypeParam { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action173( + __action174( source_code, mode, __temp0, @@ -53072,7 +53265,7 @@ fn __action950< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action951< +fn __action954< >( source_code: &str, mode: Mode, @@ -53083,14 +53276,14 @@ fn __action951< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action174( + __action175( source_code, mode, __temp0, @@ -53102,7 +53295,7 @@ fn __action951< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action952< +fn __action955< >( source_code: &str, mode: Mode, @@ -53113,14 +53306,14 @@ fn __action952< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action175( + __action176( source_code, mode, __temp0, @@ -53132,7 +53325,7 @@ fn __action952< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action953< +fn __action956< >( source_code: &str, mode: Mode, @@ -53145,14 +53338,14 @@ fn __action953< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action662( + __action665( source_code, mode, __temp0, @@ -53166,7 +53359,7 @@ fn __action953< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action954< +fn __action957< >( source_code: &str, mode: Mode, @@ -53178,14 +53371,14 @@ fn __action954< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action663( + __action666( source_code, mode, __temp0, @@ -53198,25 +53391,25 @@ fn __action954< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action955< +fn __action958< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), - __1: (TextSize, core::option::Option, TextSize), + __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::ParameterWithDefault { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action168( + __action169( source_code, mode, __temp0, @@ -53228,7 +53421,7 @@ fn __action955< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action956< +fn __action959< >( source_code: &str, mode: Mode, @@ -53238,14 +53431,14 @@ fn __action956< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action166( + __action167( source_code, mode, __temp0, @@ -53256,7 +53449,7 @@ fn __action956< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action957< +fn __action960< >( source_code: &str, mode: Mode, @@ -53266,14 +53459,14 @@ fn __action957< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action125( + __action126( source_code, mode, __temp0, @@ -53284,12 +53477,12 @@ fn __action957< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action958< +fn __action961< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), __4: (TextSize, core::option::Option, TextSize), @@ -53297,14 +53490,14 @@ fn __action958< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action146( + __action147( source_code, mode, __temp0, @@ -53318,26 +53511,26 @@ fn __action958< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action959< +fn __action962< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::WithItem { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action161( + __action162( source_code, mode, __temp0, @@ -53350,7 +53543,7 @@ fn __action959< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action960< +fn __action963< >( source_code: &str, mode: Mode, @@ -53363,14 +53556,14 @@ fn __action960< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action684( + __action687( source_code, mode, __temp0, @@ -53384,7 +53577,7 @@ fn __action960< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action961< +fn __action964< >( source_code: &str, mode: Mode, @@ -53396,14 +53589,14 @@ fn __action961< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action685( + __action688( source_code, mode, __temp0, @@ -53416,26 +53609,26 @@ fn __action961< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action962< +fn __action965< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action424( + __action427( source_code, mode, __temp0, @@ -53448,26 +53641,26 @@ fn __action962< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action963< +fn __action966< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action531( + __action534( source_code, mode, __temp0, @@ -53480,25 +53673,25 @@ fn __action963< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action964< +fn __action967< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option, TextSize), + __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action177( + __action178( source_code, mode, __temp0, @@ -53510,26 +53703,26 @@ fn __action964< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action965< +fn __action968< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action414( + let __temp0 = __action417( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action178( + __action179( source_code, mode, __temp0, @@ -53542,7 +53735,7 @@ fn __action965< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action966< +fn __action969< >( source_code: &str, mode: Mode, @@ -53555,7 +53748,7 @@ fn __action966< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action891( + let __temp0 = __action892( source_code, mode, __1, @@ -53564,7 +53757,7 @@ fn __action966< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action441( + Ok(__action444( source_code, mode, __0, @@ -53574,7 +53767,7 @@ fn __action966< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action967< +fn __action970< >( source_code: &str, mode: Mode, @@ -53586,7 +53779,7 @@ fn __action967< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action892( + let __temp0 = __action893( source_code, mode, __1, @@ -53594,7 +53787,7 @@ fn __action967< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action441( + Ok(__action444( source_code, mode, __0, @@ -53604,7 +53797,7 @@ fn __action967< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action968< +fn __action971< >( source_code: &str, mode: Mode, @@ -53618,7 +53811,7 @@ fn __action968< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action893( + let __temp0 = __action894( source_code, mode, __1, @@ -53628,7 +53821,7 @@ fn __action968< __5, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action441( + Ok(__action444( source_code, mode, __0, @@ -53638,7 +53831,7 @@ fn __action968< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action969< +fn __action972< >( source_code: &str, mode: Mode, @@ -53651,7 +53844,7 @@ fn __action969< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action894( + let __temp0 = __action895( source_code, mode, __1, @@ -53660,7 +53853,7 @@ fn __action969< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action441( + Ok(__action444( source_code, mode, __0, @@ -53670,7 +53863,7 @@ fn __action969< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action970< +fn __action973< >( source_code: &str, mode: Mode, @@ -53681,14 +53874,14 @@ fn __action970< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action895( + let __temp0 = __action896( source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action441( + Ok(__action444( source_code, mode, __0, @@ -53698,7 +53891,7 @@ fn __action970< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action971< +fn __action974< >( source_code: &str, mode: Mode, @@ -53708,13 +53901,13 @@ fn __action971< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action896( + let __temp0 = __action897( source_code, mode, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action441( + Ok(__action444( source_code, mode, __0, @@ -53724,7 +53917,7 @@ fn __action971< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action972< +fn __action975< >( source_code: &str, mode: Mode, @@ -53736,7 +53929,7 @@ fn __action972< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action897( + let __temp0 = __action898( source_code, mode, __1, @@ -53744,7 +53937,7 @@ fn __action972< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action441( + Ok(__action444( source_code, mode, __0, @@ -53754,7 +53947,7 @@ fn __action972< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action973< +fn __action976< >( source_code: &str, mode: Mode, @@ -53765,14 +53958,14 @@ fn __action973< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action898( + let __temp0 = __action899( source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action441( + Ok(__action444( source_code, mode, __0, @@ -53782,7 +53975,7 @@ fn __action973< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action974< +fn __action977< >( source_code: &str, mode: Mode, @@ -53796,7 +53989,7 @@ fn __action974< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action891( + let __temp0 = __action892( source_code, mode, __0, @@ -53805,7 +53998,7 @@ fn __action974< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action879( + Ok(__action880( source_code, mode, __temp0, @@ -53816,7 +54009,7 @@ fn __action974< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action975< +fn __action978< >( source_code: &str, mode: Mode, @@ -53829,7 +54022,7 @@ fn __action975< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action892( + let __temp0 = __action893( source_code, mode, __0, @@ -53837,7 +54030,7 @@ fn __action975< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action879( + Ok(__action880( source_code, mode, __temp0, @@ -53848,7 +54041,7 @@ fn __action975< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action976< +fn __action979< >( source_code: &str, mode: Mode, @@ -53863,7 +54056,7 @@ fn __action976< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action893( + let __temp0 = __action894( source_code, mode, __0, @@ -53873,7 +54066,7 @@ fn __action976< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action879( + Ok(__action880( source_code, mode, __temp0, @@ -53884,7 +54077,7 @@ fn __action976< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action977< +fn __action980< >( source_code: &str, mode: Mode, @@ -53898,7 +54091,7 @@ fn __action977< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action894( + let __temp0 = __action895( source_code, mode, __0, @@ -53907,7 +54100,7 @@ fn __action977< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action879( + Ok(__action880( source_code, mode, __temp0, @@ -53918,7 +54111,7 @@ fn __action977< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action978< +fn __action981< >( source_code: &str, mode: Mode, @@ -53930,14 +54123,14 @@ fn __action978< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action895( + let __temp0 = __action896( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action879( + Ok(__action880( source_code, mode, __temp0, @@ -53948,7 +54141,7 @@ fn __action978< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action979< +fn __action982< >( source_code: &str, mode: Mode, @@ -53959,13 +54152,13 @@ fn __action979< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action896( + let __temp0 = __action897( source_code, mode, __0, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action879( + Ok(__action880( source_code, mode, __temp0, @@ -53976,7 +54169,7 @@ fn __action979< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action980< +fn __action983< >( source_code: &str, mode: Mode, @@ -53989,7 +54182,7 @@ fn __action980< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action897( + let __temp0 = __action898( source_code, mode, __0, @@ -53997,7 +54190,7 @@ fn __action980< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action879( + Ok(__action880( source_code, mode, __temp0, @@ -54008,7 +54201,7 @@ fn __action980< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action981< +fn __action984< >( source_code: &str, mode: Mode, @@ -54020,14 +54213,14 @@ fn __action981< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action898( + let __temp0 = __action899( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action879( + Ok(__action880( source_code, mode, __temp0, @@ -54038,7 +54231,7 @@ fn __action981< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action982< +fn __action985< >( source_code: &str, mode: Mode, @@ -54051,7 +54244,7 @@ fn __action982< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action891( + let __temp0 = __action892( source_code, mode, __0, @@ -54060,7 +54253,7 @@ fn __action982< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action880( + Ok(__action881( source_code, mode, __temp0, @@ -54070,7 +54263,7 @@ fn __action982< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action983< +fn __action986< >( source_code: &str, mode: Mode, @@ -54082,7 +54275,7 @@ fn __action983< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action892( + let __temp0 = __action893( source_code, mode, __0, @@ -54090,7 +54283,7 @@ fn __action983< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action880( + Ok(__action881( source_code, mode, __temp0, @@ -54100,7 +54293,7 @@ fn __action983< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action984< +fn __action987< >( source_code: &str, mode: Mode, @@ -54114,7 +54307,7 @@ fn __action984< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action893( + let __temp0 = __action894( source_code, mode, __0, @@ -54124,7 +54317,7 @@ fn __action984< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action880( + Ok(__action881( source_code, mode, __temp0, @@ -54134,7 +54327,7 @@ fn __action984< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action985< +fn __action988< >( source_code: &str, mode: Mode, @@ -54147,7 +54340,7 @@ fn __action985< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action894( + let __temp0 = __action895( source_code, mode, __0, @@ -54156,7 +54349,7 @@ fn __action985< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action880( + Ok(__action881( source_code, mode, __temp0, @@ -54166,7 +54359,7 @@ fn __action985< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action986< +fn __action989< >( source_code: &str, mode: Mode, @@ -54177,14 +54370,14 @@ fn __action986< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action895( + let __temp0 = __action896( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action880( + Ok(__action881( source_code, mode, __temp0, @@ -54194,7 +54387,7 @@ fn __action986< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action987< +fn __action990< >( source_code: &str, mode: Mode, @@ -54204,13 +54397,13 @@ fn __action987< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action896( + let __temp0 = __action897( source_code, mode, __0, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action880( + Ok(__action881( source_code, mode, __temp0, @@ -54220,7 +54413,7 @@ fn __action987< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action988< +fn __action991< >( source_code: &str, mode: Mode, @@ -54232,7 +54425,7 @@ fn __action988< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action897( + let __temp0 = __action898( source_code, mode, __0, @@ -54240,7 +54433,7 @@ fn __action988< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action880( + Ok(__action881( source_code, mode, __temp0, @@ -54250,7 +54443,7 @@ fn __action988< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action989< +fn __action992< >( source_code: &str, mode: Mode, @@ -54261,14 +54454,14 @@ fn __action989< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action898( + let __temp0 = __action899( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action880( + Ok(__action881( source_code, mode, __temp0, @@ -54278,7 +54471,7 @@ fn __action989< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action990< +fn __action993< >( source_code: &str, mode: Mode, @@ -54291,7 +54484,7 @@ fn __action990< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action966( + let __temp0 = __action969( source_code, mode, __0, @@ -54301,7 +54494,7 @@ fn __action990< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action439( + Ok(__action442( source_code, mode, __temp0, @@ -54310,7 +54503,7 @@ fn __action990< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action991< +fn __action994< >( source_code: &str, mode: Mode, @@ -54322,7 +54515,7 @@ fn __action991< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action967( + let __temp0 = __action970( source_code, mode, __0, @@ -54331,7 +54524,7 @@ fn __action991< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action439( + Ok(__action442( source_code, mode, __temp0, @@ -54340,7 +54533,7 @@ fn __action991< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action992< +fn __action995< >( source_code: &str, mode: Mode, @@ -54354,7 +54547,7 @@ fn __action992< { let __start0 = __0.0; let __end0 = __5.2; - let __temp0 = __action968( + let __temp0 = __action971( source_code, mode, __0, @@ -54365,7 +54558,7 @@ fn __action992< __5, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action439( + Ok(__action442( source_code, mode, __temp0, @@ -54374,7 +54567,7 @@ fn __action992< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action993< +fn __action996< >( source_code: &str, mode: Mode, @@ -54387,7 +54580,7 @@ fn __action993< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action969( + let __temp0 = __action972( source_code, mode, __0, @@ -54397,7 +54590,7 @@ fn __action993< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action439( + Ok(__action442( source_code, mode, __temp0, @@ -54406,7 +54599,7 @@ fn __action993< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action994< +fn __action997< >( source_code: &str, mode: Mode, @@ -54417,7 +54610,7 @@ fn __action994< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action970( + let __temp0 = __action973( source_code, mode, __0, @@ -54425,7 +54618,7 @@ fn __action994< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action439( + Ok(__action442( source_code, mode, __temp0, @@ -54434,7 +54627,7 @@ fn __action994< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action995< +fn __action998< >( source_code: &str, mode: Mode, @@ -54444,14 +54637,14 @@ fn __action995< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action971( + let __temp0 = __action974( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action439( + Ok(__action442( source_code, mode, __temp0, @@ -54460,7 +54653,7 @@ fn __action995< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action996< +fn __action999< >( source_code: &str, mode: Mode, @@ -54472,7 +54665,7 @@ fn __action996< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action972( + let __temp0 = __action975( source_code, mode, __0, @@ -54481,7 +54674,7 @@ fn __action996< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action439( + Ok(__action442( source_code, mode, __temp0, @@ -54490,7 +54683,7 @@ fn __action996< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action997< +fn __action1000< >( source_code: &str, mode: Mode, @@ -54501,7 +54694,7 @@ fn __action997< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action973( + let __temp0 = __action976( source_code, mode, __0, @@ -54509,7 +54702,7 @@ fn __action997< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action439( + Ok(__action442( source_code, mode, __temp0, @@ -54518,7 +54711,7 @@ fn __action997< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action998< +fn __action1001< >( source_code: &str, mode: Mode, @@ -54534,7 +54727,7 @@ fn __action998< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action990( + let __temp0 = __action993( source_code, mode, __1, @@ -54544,7 +54737,7 @@ fn __action998< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54556,7 +54749,7 @@ fn __action998< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action999< +fn __action1002< >( source_code: &str, mode: Mode, @@ -54571,7 +54764,7 @@ fn __action999< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action991( + let __temp0 = __action994( source_code, mode, __1, @@ -54580,7 +54773,7 @@ fn __action999< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54592,7 +54785,7 @@ fn __action999< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1000< +fn __action1003< >( source_code: &str, mode: Mode, @@ -54609,7 +54802,7 @@ fn __action1000< { let __start0 = __1.0; let __end0 = __6.2; - let __temp0 = __action992( + let __temp0 = __action995( source_code, mode, __1, @@ -54620,7 +54813,7 @@ fn __action1000< __6, )?; let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54632,7 +54825,7 @@ fn __action1000< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1001< +fn __action1004< >( source_code: &str, mode: Mode, @@ -54648,7 +54841,7 @@ fn __action1001< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action993( + let __temp0 = __action996( source_code, mode, __1, @@ -54658,7 +54851,7 @@ fn __action1001< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54670,7 +54863,7 @@ fn __action1001< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1002< +fn __action1005< >( source_code: &str, mode: Mode, @@ -54684,7 +54877,7 @@ fn __action1002< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action994( + let __temp0 = __action997( source_code, mode, __1, @@ -54692,7 +54885,7 @@ fn __action1002< __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54704,7 +54897,7 @@ fn __action1002< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1003< +fn __action1006< >( source_code: &str, mode: Mode, @@ -54717,14 +54910,14 @@ fn __action1003< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action995( + let __temp0 = __action998( source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54736,7 +54929,7 @@ fn __action1003< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1004< +fn __action1007< >( source_code: &str, mode: Mode, @@ -54751,7 +54944,7 @@ fn __action1004< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action996( + let __temp0 = __action999( source_code, mode, __1, @@ -54760,7 +54953,7 @@ fn __action1004< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54772,7 +54965,7 @@ fn __action1004< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1005< +fn __action1008< >( source_code: &str, mode: Mode, @@ -54786,7 +54979,7 @@ fn __action1005< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action997( + let __temp0 = __action1000( source_code, mode, __1, @@ -54794,7 +54987,7 @@ fn __action1005< __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54806,7 +54999,7 @@ fn __action1005< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1006< +fn __action1009< >( source_code: &str, mode: Mode, @@ -54817,14 +55010,14 @@ fn __action1006< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action440( + let __temp0 = __action443( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action875( + __action876( source_code, mode, __0, @@ -54836,7 +55029,7 @@ fn __action1006< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1007< +fn __action1010< >( source_code: &str, mode: Mode, @@ -54851,7 +55044,7 @@ fn __action1007< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action990( + let __temp0 = __action993( source_code, mode, __1, @@ -54861,7 +55054,7 @@ fn __action1007< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -54872,7 +55065,7 @@ fn __action1007< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1008< +fn __action1011< >( source_code: &str, mode: Mode, @@ -54886,7 +55079,7 @@ fn __action1008< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action991( + let __temp0 = __action994( source_code, mode, __1, @@ -54895,7 +55088,7 @@ fn __action1008< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -54906,7 +55099,7 @@ fn __action1008< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1009< +fn __action1012< >( source_code: &str, mode: Mode, @@ -54922,7 +55115,7 @@ fn __action1009< { let __start0 = __1.0; let __end0 = __6.2; - let __temp0 = __action992( + let __temp0 = __action995( source_code, mode, __1, @@ -54933,7 +55126,7 @@ fn __action1009< __6, )?; let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -54944,7 +55137,7 @@ fn __action1009< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1010< +fn __action1013< >( source_code: &str, mode: Mode, @@ -54959,7 +55152,7 @@ fn __action1010< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action993( + let __temp0 = __action996( source_code, mode, __1, @@ -54969,7 +55162,7 @@ fn __action1010< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -54980,7 +55173,7 @@ fn __action1010< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1011< +fn __action1014< >( source_code: &str, mode: Mode, @@ -54993,7 +55186,7 @@ fn __action1011< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action994( + let __temp0 = __action997( source_code, mode, __1, @@ -55001,7 +55194,7 @@ fn __action1011< __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -55012,7 +55205,7 @@ fn __action1011< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1012< +fn __action1015< >( source_code: &str, mode: Mode, @@ -55024,14 +55217,14 @@ fn __action1012< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action995( + let __temp0 = __action998( source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -55042,7 +55235,7 @@ fn __action1012< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1013< +fn __action1016< >( source_code: &str, mode: Mode, @@ -55056,7 +55249,7 @@ fn __action1013< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action996( + let __temp0 = __action999( source_code, mode, __1, @@ -55065,7 +55258,7 @@ fn __action1013< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -55076,7 +55269,7 @@ fn __action1013< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1014< +fn __action1017< >( source_code: &str, mode: Mode, @@ -55089,7 +55282,7 @@ fn __action1014< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action997( + let __temp0 = __action1000( source_code, mode, __1, @@ -55097,7 +55290,7 @@ fn __action1014< __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -55108,7 +55301,7 @@ fn __action1014< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1015< +fn __action1018< >( source_code: &str, mode: Mode, @@ -55118,14 +55311,14 @@ fn __action1015< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action440( + let __temp0 = __action443( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action876( + __action877( source_code, mode, __0, @@ -55136,7 +55329,7 @@ fn __action1015< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1016< +fn __action1019< >( source_code: &str, mode: Mode, @@ -55146,13 +55339,13 @@ fn __action1016< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action485( + let __temp0 = __action488( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action446( + __action449( source_code, mode, __0, @@ -55162,7 +55355,7 @@ fn __action1016< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1017< +fn __action1020< >( source_code: &str, mode: Mode, @@ -55171,14 +55364,14 @@ fn __action1017< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action486( + let __temp0 = __action489( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action446( + __action449( source_code, mode, __0, @@ -55188,7 +55381,7 @@ fn __action1017< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1018< +fn __action1021< >( source_code: &str, mode: Mode, @@ -55200,13 +55393,13 @@ fn __action1018< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action485( + let __temp0 = __action488( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action899( + __action900( source_code, mode, __0, @@ -55218,7 +55411,7 @@ fn __action1018< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1019< +fn __action1022< >( source_code: &str, mode: Mode, @@ -55229,14 +55422,14 @@ fn __action1019< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action486( + let __temp0 = __action489( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action899( + __action900( source_code, mode, __0, @@ -55248,7 +55441,7 @@ fn __action1019< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1020< +fn __action1023< >( source_code: &str, mode: Mode, @@ -55261,13 +55454,13 @@ fn __action1020< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action485( + let __temp0 = __action488( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action900( + __action901( source_code, mode, __0, @@ -55280,7 +55473,7 @@ fn __action1020< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1021< +fn __action1024< >( source_code: &str, mode: Mode, @@ -55292,14 +55485,14 @@ fn __action1021< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action486( + let __temp0 = __action489( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action900( + __action901( source_code, mode, __0, @@ -55312,7 +55505,7 @@ fn __action1021< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1022< +fn __action1025< >( source_code: &str, mode: Mode, @@ -55322,13 +55515,13 @@ fn __action1022< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action485( + let __temp0 = __action488( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action901( + __action902( source_code, mode, __0, @@ -55338,7 +55531,7 @@ fn __action1022< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1023< +fn __action1026< >( source_code: &str, mode: Mode, @@ -55347,14 +55540,14 @@ fn __action1023< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action486( + let __temp0 = __action489( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action901( + __action902( source_code, mode, __0, @@ -55364,7 +55557,7 @@ fn __action1023< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1024< +fn __action1027< >( source_code: &str, mode: Mode, @@ -55375,13 +55568,13 @@ fn __action1024< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action485( + let __temp0 = __action488( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action902( + __action903( source_code, mode, __0, @@ -55392,7 +55585,7 @@ fn __action1024< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1025< +fn __action1028< >( source_code: &str, mode: Mode, @@ -55402,14 +55595,14 @@ fn __action1025< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action486( + let __temp0 = __action489( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action902( + __action903( source_code, mode, __0, @@ -55420,7 +55613,7 @@ fn __action1025< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1026< +fn __action1029< >( source_code: &str, mode: Mode, @@ -55433,7 +55626,7 @@ fn __action1026< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1018( + let __temp0 = __action1021( source_code, mode, __1, @@ -55442,7 +55635,7 @@ fn __action1026< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action449( + Ok(__action452( source_code, mode, __0, @@ -55452,7 +55645,7 @@ fn __action1026< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1027< +fn __action1030< >( source_code: &str, mode: Mode, @@ -55464,7 +55657,7 @@ fn __action1027< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1019( + let __temp0 = __action1022( source_code, mode, __1, @@ -55472,7 +55665,7 @@ fn __action1027< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action449( + Ok(__action452( source_code, mode, __0, @@ -55482,7 +55675,7 @@ fn __action1027< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1028< +fn __action1031< >( source_code: &str, mode: Mode, @@ -55496,7 +55689,7 @@ fn __action1028< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1020( + let __temp0 = __action1023( source_code, mode, __1, @@ -55506,7 +55699,7 @@ fn __action1028< __5, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action449( + Ok(__action452( source_code, mode, __0, @@ -55516,7 +55709,7 @@ fn __action1028< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1029< +fn __action1032< >( source_code: &str, mode: Mode, @@ -55529,7 +55722,7 @@ fn __action1029< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1021( + let __temp0 = __action1024( source_code, mode, __1, @@ -55538,7 +55731,7 @@ fn __action1029< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action449( + Ok(__action452( source_code, mode, __0, @@ -55548,7 +55741,7 @@ fn __action1029< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1030< +fn __action1033< >( source_code: &str, mode: Mode, @@ -55559,14 +55752,14 @@ fn __action1030< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1022( + let __temp0 = __action1025( source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action449( + Ok(__action452( source_code, mode, __0, @@ -55576,7 +55769,7 @@ fn __action1030< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1031< +fn __action1034< >( source_code: &str, mode: Mode, @@ -55586,13 +55779,13 @@ fn __action1031< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1023( + let __temp0 = __action1026( source_code, mode, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action449( + Ok(__action452( source_code, mode, __0, @@ -55602,7 +55795,7 @@ fn __action1031< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1032< +fn __action1035< >( source_code: &str, mode: Mode, @@ -55614,7 +55807,7 @@ fn __action1032< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1024( + let __temp0 = __action1027( source_code, mode, __1, @@ -55622,7 +55815,7 @@ fn __action1032< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action449( + Ok(__action452( source_code, mode, __0, @@ -55632,7 +55825,7 @@ fn __action1032< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1033< +fn __action1036< >( source_code: &str, mode: Mode, @@ -55643,14 +55836,14 @@ fn __action1033< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1025( + let __temp0 = __action1028( source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action449( + Ok(__action452( source_code, mode, __0, @@ -55660,7 +55853,7 @@ fn __action1033< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1034< +fn __action1037< >( source_code: &str, mode: Mode, @@ -55674,7 +55867,7 @@ fn __action1034< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action1018( + let __temp0 = __action1021( source_code, mode, __0, @@ -55683,7 +55876,7 @@ fn __action1034< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action887( + Ok(__action888( source_code, mode, __temp0, @@ -55694,7 +55887,7 @@ fn __action1034< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1035< +fn __action1038< >( source_code: &str, mode: Mode, @@ -55707,7 +55900,7 @@ fn __action1035< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1019( + let __temp0 = __action1022( source_code, mode, __0, @@ -55715,7 +55908,7 @@ fn __action1035< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action887( + Ok(__action888( source_code, mode, __temp0, @@ -55726,7 +55919,7 @@ fn __action1035< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1036< +fn __action1039< >( source_code: &str, mode: Mode, @@ -55741,7 +55934,7 @@ fn __action1036< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action1020( + let __temp0 = __action1023( source_code, mode, __0, @@ -55751,7 +55944,7 @@ fn __action1036< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action887( + Ok(__action888( source_code, mode, __temp0, @@ -55762,7 +55955,7 @@ fn __action1036< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1037< +fn __action1040< >( source_code: &str, mode: Mode, @@ -55776,7 +55969,7 @@ fn __action1037< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action1021( + let __temp0 = __action1024( source_code, mode, __0, @@ -55785,7 +55978,7 @@ fn __action1037< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action887( + Ok(__action888( source_code, mode, __temp0, @@ -55796,7 +55989,7 @@ fn __action1037< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1038< +fn __action1041< >( source_code: &str, mode: Mode, @@ -55808,14 +56001,14 @@ fn __action1038< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action1022( + let __temp0 = __action1025( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action887( + Ok(__action888( source_code, mode, __temp0, @@ -55826,7 +56019,7 @@ fn __action1038< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1039< +fn __action1042< >( source_code: &str, mode: Mode, @@ -55837,13 +56030,13 @@ fn __action1039< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1023( + let __temp0 = __action1026( source_code, mode, __0, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action887( + Ok(__action888( source_code, mode, __temp0, @@ -55854,7 +56047,7 @@ fn __action1039< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1040< +fn __action1043< >( source_code: &str, mode: Mode, @@ -55867,7 +56060,7 @@ fn __action1040< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1024( + let __temp0 = __action1027( source_code, mode, __0, @@ -55875,7 +56068,7 @@ fn __action1040< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action887( + Ok(__action888( source_code, mode, __temp0, @@ -55886,7 +56079,7 @@ fn __action1040< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1041< +fn __action1044< >( source_code: &str, mode: Mode, @@ -55898,14 +56091,14 @@ fn __action1041< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action1025( + let __temp0 = __action1028( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action887( + Ok(__action888( source_code, mode, __temp0, @@ -55916,7 +56109,7 @@ fn __action1041< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1042< +fn __action1045< >( source_code: &str, mode: Mode, @@ -55929,7 +56122,7 @@ fn __action1042< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action1018( + let __temp0 = __action1021( source_code, mode, __0, @@ -55938,7 +56131,7 @@ fn __action1042< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action888( + Ok(__action889( source_code, mode, __temp0, @@ -55948,7 +56141,7 @@ fn __action1042< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1043< +fn __action1046< >( source_code: &str, mode: Mode, @@ -55960,7 +56153,7 @@ fn __action1043< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1019( + let __temp0 = __action1022( source_code, mode, __0, @@ -55968,7 +56161,7 @@ fn __action1043< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action888( + Ok(__action889( source_code, mode, __temp0, @@ -55978,7 +56171,7 @@ fn __action1043< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1044< +fn __action1047< >( source_code: &str, mode: Mode, @@ -55992,7 +56185,7 @@ fn __action1044< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action1020( + let __temp0 = __action1023( source_code, mode, __0, @@ -56002,7 +56195,7 @@ fn __action1044< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action888( + Ok(__action889( source_code, mode, __temp0, @@ -56012,7 +56205,7 @@ fn __action1044< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1045< +fn __action1048< >( source_code: &str, mode: Mode, @@ -56025,7 +56218,7 @@ fn __action1045< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action1021( + let __temp0 = __action1024( source_code, mode, __0, @@ -56034,7 +56227,7 @@ fn __action1045< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action888( + Ok(__action889( source_code, mode, __temp0, @@ -56044,7 +56237,7 @@ fn __action1045< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1046< +fn __action1049< >( source_code: &str, mode: Mode, @@ -56055,14 +56248,14 @@ fn __action1046< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action1022( + let __temp0 = __action1025( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action888( + Ok(__action889( source_code, mode, __temp0, @@ -56072,7 +56265,7 @@ fn __action1046< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1047< +fn __action1050< >( source_code: &str, mode: Mode, @@ -56082,13 +56275,13 @@ fn __action1047< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1023( + let __temp0 = __action1026( source_code, mode, __0, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action888( + Ok(__action889( source_code, mode, __temp0, @@ -56098,7 +56291,7 @@ fn __action1047< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1048< +fn __action1051< >( source_code: &str, mode: Mode, @@ -56110,7 +56303,7 @@ fn __action1048< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1024( + let __temp0 = __action1027( source_code, mode, __0, @@ -56118,7 +56311,7 @@ fn __action1048< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action888( + Ok(__action889( source_code, mode, __temp0, @@ -56128,7 +56321,7 @@ fn __action1048< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1049< +fn __action1052< >( source_code: &str, mode: Mode, @@ -56139,14 +56332,14 @@ fn __action1049< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action1025( + let __temp0 = __action1028( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action888( + Ok(__action889( source_code, mode, __temp0, @@ -56156,7 +56349,7 @@ fn __action1049< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1050< +fn __action1053< >( source_code: &str, mode: Mode, @@ -56169,7 +56362,7 @@ fn __action1050< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action1026( + let __temp0 = __action1029( source_code, mode, __0, @@ -56179,7 +56372,7 @@ fn __action1050< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action447( + Ok(__action450( source_code, mode, __temp0, @@ -56188,7 +56381,7 @@ fn __action1050< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1051< +fn __action1054< >( source_code: &str, mode: Mode, @@ -56200,7 +56393,7 @@ fn __action1051< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action1027( + let __temp0 = __action1030( source_code, mode, __0, @@ -56209,7 +56402,7 @@ fn __action1051< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action447( + Ok(__action450( source_code, mode, __temp0, @@ -56218,7 +56411,7 @@ fn __action1051< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1052< +fn __action1055< >( source_code: &str, mode: Mode, @@ -56232,7 +56425,7 @@ fn __action1052< { let __start0 = __0.0; let __end0 = __5.2; - let __temp0 = __action1028( + let __temp0 = __action1031( source_code, mode, __0, @@ -56243,7 +56436,7 @@ fn __action1052< __5, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action447( + Ok(__action450( source_code, mode, __temp0, @@ -56252,7 +56445,7 @@ fn __action1052< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1053< +fn __action1056< >( source_code: &str, mode: Mode, @@ -56265,7 +56458,7 @@ fn __action1053< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action1029( + let __temp0 = __action1032( source_code, mode, __0, @@ -56275,7 +56468,7 @@ fn __action1053< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action447( + Ok(__action450( source_code, mode, __temp0, @@ -56284,7 +56477,7 @@ fn __action1053< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1054< +fn __action1057< >( source_code: &str, mode: Mode, @@ -56295,7 +56488,7 @@ fn __action1054< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1030( + let __temp0 = __action1033( source_code, mode, __0, @@ -56303,7 +56496,7 @@ fn __action1054< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action447( + Ok(__action450( source_code, mode, __temp0, @@ -56312,7 +56505,7 @@ fn __action1054< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1055< +fn __action1058< >( source_code: &str, mode: Mode, @@ -56322,14 +56515,14 @@ fn __action1055< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action1031( + let __temp0 = __action1034( source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action447( + Ok(__action450( source_code, mode, __temp0, @@ -56338,7 +56531,7 @@ fn __action1055< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1056< +fn __action1059< >( source_code: &str, mode: Mode, @@ -56350,7 +56543,7 @@ fn __action1056< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action1032( + let __temp0 = __action1035( source_code, mode, __0, @@ -56359,7 +56552,7 @@ fn __action1056< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action447( + Ok(__action450( source_code, mode, __temp0, @@ -56368,7 +56561,7 @@ fn __action1056< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1057< +fn __action1060< >( source_code: &str, mode: Mode, @@ -56379,7 +56572,7 @@ fn __action1057< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1033( + let __temp0 = __action1036( source_code, mode, __0, @@ -56387,7 +56580,7 @@ fn __action1057< __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action447( + Ok(__action450( source_code, mode, __temp0, @@ -56396,7 +56589,7 @@ fn __action1057< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1058< +fn __action1061< >( source_code: &str, mode: Mode, @@ -56412,7 +56605,7 @@ fn __action1058< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1050( + let __temp0 = __action1053( source_code, mode, __1, @@ -56422,7 +56615,7 @@ fn __action1058< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56434,7 +56627,7 @@ fn __action1058< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1059< +fn __action1062< >( source_code: &str, mode: Mode, @@ -56449,7 +56642,7 @@ fn __action1059< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1051( + let __temp0 = __action1054( source_code, mode, __1, @@ -56458,7 +56651,7 @@ fn __action1059< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56470,7 +56663,7 @@ fn __action1059< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1060< +fn __action1063< >( source_code: &str, mode: Mode, @@ -56487,7 +56680,7 @@ fn __action1060< { let __start0 = __1.0; let __end0 = __6.2; - let __temp0 = __action1052( + let __temp0 = __action1055( source_code, mode, __1, @@ -56498,7 +56691,7 @@ fn __action1060< __6, )?; let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56510,7 +56703,7 @@ fn __action1060< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1061< +fn __action1064< >( source_code: &str, mode: Mode, @@ -56526,7 +56719,7 @@ fn __action1061< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1053( + let __temp0 = __action1056( source_code, mode, __1, @@ -56536,7 +56729,7 @@ fn __action1061< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56548,7 +56741,7 @@ fn __action1061< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1062< +fn __action1065< >( source_code: &str, mode: Mode, @@ -56562,7 +56755,7 @@ fn __action1062< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1054( + let __temp0 = __action1057( source_code, mode, __1, @@ -56570,7 +56763,7 @@ fn __action1062< __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56582,7 +56775,7 @@ fn __action1062< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1063< +fn __action1066< >( source_code: &str, mode: Mode, @@ -56595,14 +56788,14 @@ fn __action1063< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1055( + let __temp0 = __action1058( source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56614,7 +56807,7 @@ fn __action1063< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1064< +fn __action1067< >( source_code: &str, mode: Mode, @@ -56629,7 +56822,7 @@ fn __action1064< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1056( + let __temp0 = __action1059( source_code, mode, __1, @@ -56638,7 +56831,7 @@ fn __action1064< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56650,7 +56843,7 @@ fn __action1064< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1065< +fn __action1068< >( source_code: &str, mode: Mode, @@ -56664,7 +56857,7 @@ fn __action1065< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1057( + let __temp0 = __action1060( source_code, mode, __1, @@ -56672,7 +56865,7 @@ fn __action1065< __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56684,7 +56877,7 @@ fn __action1065< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1066< +fn __action1069< >( source_code: &str, mode: Mode, @@ -56695,14 +56888,14 @@ fn __action1066< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action448( + let __temp0 = __action451( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action883( + __action884( source_code, mode, __0, @@ -56714,7 +56907,7 @@ fn __action1066< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1067< +fn __action1070< >( source_code: &str, mode: Mode, @@ -56729,7 +56922,7 @@ fn __action1067< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1050( + let __temp0 = __action1053( source_code, mode, __1, @@ -56739,7 +56932,7 @@ fn __action1067< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -56750,7 +56943,7 @@ fn __action1067< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1068< +fn __action1071< >( source_code: &str, mode: Mode, @@ -56764,7 +56957,7 @@ fn __action1068< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1051( + let __temp0 = __action1054( source_code, mode, __1, @@ -56773,7 +56966,7 @@ fn __action1068< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -56784,7 +56977,7 @@ fn __action1068< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1069< +fn __action1072< >( source_code: &str, mode: Mode, @@ -56800,7 +56993,7 @@ fn __action1069< { let __start0 = __1.0; let __end0 = __6.2; - let __temp0 = __action1052( + let __temp0 = __action1055( source_code, mode, __1, @@ -56811,7 +57004,7 @@ fn __action1069< __6, )?; let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -56822,7 +57015,7 @@ fn __action1069< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1070< +fn __action1073< >( source_code: &str, mode: Mode, @@ -56837,7 +57030,7 @@ fn __action1070< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1053( + let __temp0 = __action1056( source_code, mode, __1, @@ -56847,7 +57040,7 @@ fn __action1070< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -56858,7 +57051,7 @@ fn __action1070< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1071< +fn __action1074< >( source_code: &str, mode: Mode, @@ -56871,7 +57064,7 @@ fn __action1071< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1054( + let __temp0 = __action1057( source_code, mode, __1, @@ -56879,7 +57072,7 @@ fn __action1071< __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -56890,7 +57083,7 @@ fn __action1071< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1072< +fn __action1075< >( source_code: &str, mode: Mode, @@ -56902,14 +57095,14 @@ fn __action1072< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1055( + let __temp0 = __action1058( source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -56920,7 +57113,7 @@ fn __action1072< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1073< +fn __action1076< >( source_code: &str, mode: Mode, @@ -56934,7 +57127,7 @@ fn __action1073< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1056( + let __temp0 = __action1059( source_code, mode, __1, @@ -56943,7 +57136,7 @@ fn __action1073< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -56954,7 +57147,7 @@ fn __action1073< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1074< +fn __action1077< >( source_code: &str, mode: Mode, @@ -56967,7 +57160,7 @@ fn __action1074< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1057( + let __temp0 = __action1060( source_code, mode, __1, @@ -56975,7 +57168,7 @@ fn __action1074< __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -56986,7 +57179,7 @@ fn __action1074< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1075< +fn __action1078< >( source_code: &str, mode: Mode, @@ -56996,14 +57189,14 @@ fn __action1075< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action448( + let __temp0 = __action451( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action884( + __action885( source_code, mode, __0, @@ -57014,24 +57207,24 @@ fn __action1075< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1076< +fn __action1079< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action375( + let __temp0 = __action378( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action373( + __action376( source_code, mode, __temp0, @@ -57040,27 +57233,27 @@ fn __action1076< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1077< +fn __action1080< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action1076( + let __temp0 = __action1079( source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action731( + __action734( source_code, mode, __0, @@ -57072,25 +57265,25 @@ fn __action1077< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1078< +fn __action1081< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action374( + let __temp0 = __action377( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action731( + __action734( source_code, mode, __0, @@ -57102,24 +57295,24 @@ fn __action1078< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1079< +fn __action1082< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action568( + let __temp0 = __action571( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action578( + __action581( source_code, mode, __temp0, @@ -57128,25 +57321,25 @@ fn __action1079< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1080< +fn __action1083< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action568( + let __temp0 = __action571( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action579( + __action582( source_code, mode, __0, @@ -57156,28 +57349,28 @@ fn __action1080< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1081< +fn __action1084< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action566( + let __temp0 = __action569( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action739( + __action741( source_code, mode, __0, @@ -57192,28 +57385,28 @@ fn __action1081< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1082< +fn __action1085< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action567( + let __temp0 = __action570( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action739( + __action741( source_code, mode, __0, @@ -57228,27 +57421,27 @@ fn __action1082< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1083< +fn __action1086< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action566( + let __temp0 = __action569( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action740( + __action742( source_code, mode, __0, @@ -57262,27 +57455,27 @@ fn __action1083< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1084< +fn __action1087< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action567( + let __temp0 = __action570( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action740( + __action742( source_code, mode, __0, @@ -57296,28 +57489,28 @@ fn __action1084< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1085< +fn __action1088< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action566( + let __temp0 = __action569( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action758( + __action759( source_code, mode, __0, @@ -57332,28 +57525,28 @@ fn __action1085< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1086< +fn __action1089< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action567( + let __temp0 = __action570( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action758( + __action759( source_code, mode, __0, @@ -57368,27 +57561,27 @@ fn __action1086< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1087< +fn __action1090< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action566( + let __temp0 = __action569( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action759( + __action760( source_code, mode, __0, @@ -57402,27 +57595,27 @@ fn __action1087< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1088< +fn __action1091< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, core::option::Option>, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action567( + let __temp0 = __action570( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action759( + __action760( source_code, mode, __0, @@ -57436,7 +57629,7 @@ fn __action1088< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1089< +fn __action1092< >( source_code: &str, mode: Mode, @@ -57446,14 +57639,14 @@ fn __action1089< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action316( + let __temp0 = __action321( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action310( + __action315( source_code, mode, __temp0, @@ -57462,7 +57655,7 @@ fn __action1089< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1090< +fn __action1093< >( source_code: &str, mode: Mode, @@ -57473,14 +57666,14 @@ fn __action1090< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action316( + let __temp0 = __action321( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action311( + __action316( source_code, mode, __0, @@ -57490,7 +57683,7 @@ fn __action1090< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1091< +fn __action1094< >( source_code: &str, mode: Mode, @@ -57503,14 +57696,14 @@ fn __action1091< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action314( + let __temp0 = __action319( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action666( + __action669( source_code, mode, __0, @@ -57524,7 +57717,7 @@ fn __action1091< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1092< +fn __action1095< >( source_code: &str, mode: Mode, @@ -57538,13 +57731,13 @@ fn __action1092< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action315( + let __temp0 = __action320( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action666( + __action669( source_code, mode, __0, @@ -57558,7 +57751,7 @@ fn __action1092< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1093< +fn __action1096< >( source_code: &str, mode: Mode, @@ -57570,14 +57763,14 @@ fn __action1093< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action314( + let __temp0 = __action319( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action667( + __action670( source_code, mode, __0, @@ -57590,7 +57783,7 @@ fn __action1093< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1094< +fn __action1097< >( source_code: &str, mode: Mode, @@ -57603,13 +57796,13 @@ fn __action1094< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action315( + let __temp0 = __action320( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action667( + __action670( source_code, mode, __0, @@ -57622,24 +57815,24 @@ fn __action1094< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1095< +fn __action1098< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action303( + let __temp0 = __action308( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action301( + __action306( source_code, mode, __temp0, @@ -57648,7 +57841,7 @@ fn __action1095< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1096< +fn __action1099< >( source_code: &str, mode: Mode, @@ -57659,21 +57852,21 @@ fn __action1096< __4: (TextSize, core::option::Option, TextSize), __5: (TextSize, ast::Parameters, TextSize), __6: (TextSize, token::Tok, TextSize), - __7: (TextSize, ast::ParenthesizedExpr, TextSize), + __7: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __8: (TextSize, token::Tok, TextSize), __9: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __6.0; let __end0 = __7.2; - let __temp0 = __action1095( + let __temp0 = __action1098( source_code, mode, __6, __7, ); let __temp0 = (__start0, __temp0, __end0); - __action814( + __action815( source_code, mode, __0, @@ -57690,7 +57883,7 @@ fn __action1096< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1097< +fn __action1100< >( source_code: &str, mode: Mode, @@ -57706,14 +57899,14 @@ fn __action1097< { let __start0 = __5.2; let __end0 = __6.0; - let __temp0 = __action302( + let __temp0 = __action307( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action814( + __action815( source_code, mode, __0, @@ -57730,7 +57923,7 @@ fn __action1097< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1098< +fn __action1101< >( source_code: &str, mode: Mode, @@ -57740,21 +57933,21 @@ fn __action1098< __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, ast::Parameters, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::ParenthesizedExpr, TextSize), + __6: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __7: (TextSize, token::Tok, TextSize), __8: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __5.0; let __end0 = __6.2; - let __temp0 = __action1095( + let __temp0 = __action1098( source_code, mode, __5, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action815( + __action816( source_code, mode, __0, @@ -57770,7 +57963,7 @@ fn __action1098< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1099< +fn __action1102< >( source_code: &str, mode: Mode, @@ -57785,14 +57978,14 @@ fn __action1099< { let __start0 = __4.2; let __end0 = __5.0; - let __temp0 = __action302( + let __temp0 = __action307( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action815( + __action816( source_code, mode, __0, @@ -57808,7 +58001,7 @@ fn __action1099< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1100< +fn __action1103< >( source_code: &str, mode: Mode, @@ -57818,14 +58011,14 @@ fn __action1100< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action380( + let __temp0 = __action383( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action378( + __action381( source_code, mode, __temp0, @@ -57834,7 +58027,7 @@ fn __action1100< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1101< +fn __action1104< >( source_code: &str, mode: Mode, @@ -57845,14 +58038,14 @@ fn __action1101< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action380( + let __temp0 = __action383( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action379( + __action382( source_code, mode, __0, @@ -57862,24 +58055,24 @@ fn __action1101< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1102< +fn __action1105< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action293( + let __temp0 = __action298( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action291( + __action296( source_code, mode, __temp0, @@ -57888,26 +58081,26 @@ fn __action1102< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1103< +fn __action1106< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::Parameter { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1102( + let __temp0 = __action1105( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action790( + __action791( source_code, mode, __0, @@ -57918,7 +58111,7 @@ fn __action1103< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1104< +fn __action1107< >( source_code: &str, mode: Mode, @@ -57928,14 +58121,14 @@ fn __action1104< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action292( + let __temp0 = __action297( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action790( + __action791( source_code, mode, __0, @@ -57946,26 +58139,26 @@ fn __action1104< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1105< +fn __action1108< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::TypeParam { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1102( + let __temp0 = __action1105( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action950( + __action953( source_code, mode, __0, @@ -57976,7 +58169,7 @@ fn __action1105< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1106< +fn __action1109< >( source_code: &str, mode: Mode, @@ -57986,14 +58179,14 @@ fn __action1106< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action292( + let __temp0 = __action297( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action950( + __action953( source_code, mode, __0, @@ -58004,26 +58197,26 @@ fn __action1106< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1107< +fn __action1110< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::ParameterWithDefault { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1102( + let __temp0 = __action1105( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action955( + __action958( source_code, mode, __0, @@ -58034,7 +58227,7 @@ fn __action1107< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1108< +fn __action1111< >( source_code: &str, mode: Mode, @@ -58044,14 +58237,14 @@ fn __action1108< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action292( + let __temp0 = __action297( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action955( + __action958( source_code, mode, __0, @@ -58062,24 +58255,24 @@ fn __action1108< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1109< +fn __action1112< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action290( + let __temp0 = __action295( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action288( + __action293( source_code, mode, __temp0, @@ -58088,26 +58281,26 @@ fn __action1109< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1110< +fn __action1113< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::Parameter { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1109( + let __temp0 = __action1112( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action932( + __action933( source_code, mode, __0, @@ -58118,7 +58311,7 @@ fn __action1110< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1111< +fn __action1114< >( source_code: &str, mode: Mode, @@ -58128,14 +58321,14 @@ fn __action1111< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action289( + let __temp0 = __action294( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action932( + __action933( source_code, mode, __0, @@ -58146,7 +58339,7 @@ fn __action1111< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1112< +fn __action1115< >( source_code: &str, mode: Mode, @@ -58155,13 +58348,13 @@ fn __action1112< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action370( + let __temp0 = __action373( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action368( + __action371( source_code, mode, __temp0, @@ -58170,7 +58363,7 @@ fn __action1112< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1113< +fn __action1116< >( source_code: &str, mode: Mode, @@ -58180,13 +58373,13 @@ fn __action1113< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action370( + let __temp0 = __action373( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action369( + __action372( source_code, mode, __0, @@ -58196,7 +58389,7 @@ fn __action1113< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1114< +fn __action1117< >( source_code: &str, mode: Mode, @@ -58205,13 +58398,13 @@ fn __action1114< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action412( + let __temp0 = __action415( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action415( + __action418( source_code, mode, __temp0, @@ -58220,7 +58413,7 @@ fn __action1114< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1115< +fn __action1118< >( source_code: &str, mode: Mode, @@ -58230,13 +58423,13 @@ fn __action1115< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action412( + let __temp0 = __action415( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action416( + __action419( source_code, mode, __0, @@ -58246,25 +58439,25 @@ fn __action1115< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1116< +fn __action1119< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::Mod { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action410( + let __temp0 = __action413( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action944( + __action947( source_code, mode, __0, @@ -58276,25 +58469,25 @@ fn __action1116< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1117< +fn __action1120< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, TextSize, TextSize), ) -> ast::Mod { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action411( + let __temp0 = __action414( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action944( + __action947( source_code, mode, __0, @@ -58306,7 +58499,7 @@ fn __action1117< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1118< +fn __action1121< >( source_code: &str, mode: Mode, @@ -58316,14 +58509,14 @@ fn __action1118< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action423( + let __temp0 = __action426( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action421( + __action424( source_code, mode, __temp0, @@ -58332,7 +58525,7 @@ fn __action1118< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1119< +fn __action1122< >( source_code: &str, mode: Mode, @@ -58344,14 +58537,14 @@ fn __action1119< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1118( + let __temp0 = __action1121( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action827( + __action828( source_code, mode, __0, @@ -58362,7 +58555,7 @@ fn __action1119< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1120< +fn __action1123< >( source_code: &str, mode: Mode, @@ -58372,14 +58565,14 @@ fn __action1120< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action422( + let __temp0 = __action425( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action827( + __action828( source_code, mode, __0, @@ -58390,7 +58583,7 @@ fn __action1120< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1121< +fn __action1124< >( source_code: &str, mode: Mode, @@ -58402,14 +58595,14 @@ fn __action1121< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1118( + let __temp0 = __action1121( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action828( + __action829( source_code, mode, __0, @@ -58420,7 +58613,7 @@ fn __action1121< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1122< +fn __action1125< >( source_code: &str, mode: Mode, @@ -58430,14 +58623,14 @@ fn __action1122< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action422( + let __temp0 = __action425( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action828( + __action829( source_code, mode, __0, @@ -58448,7 +58641,7 @@ fn __action1122< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1123< +fn __action1126< >( source_code: &str, mode: Mode, @@ -58459,7 +58652,7 @@ fn __action1123< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action336( + let __temp0 = __action341( source_code, mode, __0, @@ -58467,7 +58660,7 @@ fn __action1123< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action334( + __action339( source_code, mode, __temp0, @@ -58476,15 +58669,15 @@ fn __action1123< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1124< +fn __action1127< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, ast::Suite, TextSize), __7: (TextSize, token::Tok, TextSize), @@ -58494,7 +58687,7 @@ fn __action1124< { let __start0 = __7.0; let __end0 = __9.2; - let __temp0 = __action1123( + let __temp0 = __action1126( source_code, mode, __7, @@ -58502,7 +58695,7 @@ fn __action1124< __9, ); let __temp0 = (__start0, __temp0, __end0); - __action812( + __action813( source_code, mode, __0, @@ -58518,29 +58711,29 @@ fn __action1124< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1125< +fn __action1128< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action335( + let __temp0 = __action340( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action812( + __action813( source_code, mode, __0, @@ -58556,14 +58749,14 @@ fn __action1125< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1126< +fn __action1129< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, ast::Suite, TextSize), __6: (TextSize, token::Tok, TextSize), @@ -58573,7 +58766,7 @@ fn __action1126< { let __start0 = __6.0; let __end0 = __8.2; - let __temp0 = __action1123( + let __temp0 = __action1126( source_code, mode, __6, @@ -58581,7 +58774,7 @@ fn __action1126< __8, ); let __temp0 = (__start0, __temp0, __end0); - __action813( + __action814( source_code, mode, __0, @@ -58596,28 +58789,28 @@ fn __action1126< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1127< +fn __action1130< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action335( + let __temp0 = __action340( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action813( + __action814( source_code, mode, __0, @@ -58632,7 +58825,7 @@ fn __action1127< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1128< +fn __action1131< >( source_code: &str, mode: Mode, @@ -58649,7 +58842,7 @@ fn __action1128< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1123( + let __temp0 = __action1126( source_code, mode, __4, @@ -58657,7 +58850,7 @@ fn __action1128< __6, ); let __temp0 = (__start0, __temp0, __end0); - __action945( + __action948( source_code, mode, __0, @@ -58672,7 +58865,7 @@ fn __action1128< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1129< +fn __action1132< >( source_code: &str, mode: Mode, @@ -58686,14 +58879,14 @@ fn __action1129< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action335( + let __temp0 = __action340( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action945( + __action948( source_code, mode, __0, @@ -58708,7 +58901,7 @@ fn __action1129< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1130< +fn __action1133< >( source_code: &str, mode: Mode, @@ -58725,7 +58918,7 @@ fn __action1130< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1123( + let __temp0 = __action1126( source_code, mode, __4, @@ -58733,7 +58926,7 @@ fn __action1130< __6, ); let __temp0 = (__start0, __temp0, __end0); - __action946( + __action949( source_code, mode, __0, @@ -58748,7 +58941,7 @@ fn __action1130< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1131< +fn __action1134< >( source_code: &str, mode: Mode, @@ -58762,14 +58955,14 @@ fn __action1131< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action335( + let __temp0 = __action340( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action946( + __action949( source_code, mode, __0, @@ -58784,12 +58977,12 @@ fn __action1131< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1132< +fn __action1135< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -58799,7 +58992,7 @@ fn __action1132< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1123( + let __temp0 = __action1126( source_code, mode, __4, @@ -58807,7 +59000,7 @@ fn __action1132< __6, ); let __temp0 = (__start0, __temp0, __end0); - __action958( + __action961( source_code, mode, __0, @@ -58820,26 +59013,26 @@ fn __action1132< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1133< +fn __action1136< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action335( + let __temp0 = __action340( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action958( + __action961( source_code, mode, __0, @@ -58852,7 +59045,7 @@ fn __action1133< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1134< +fn __action1137< >( source_code: &str, mode: Mode, @@ -58863,7 +59056,7 @@ fn __action1134< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action329( + let __temp0 = __action334( source_code, mode, __0, @@ -58871,7 +59064,7 @@ fn __action1134< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action327( + __action332( source_code, mode, __temp0, @@ -58880,7 +59073,7 @@ fn __action1134< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1135< +fn __action1138< >( source_code: &str, mode: Mode, @@ -58894,7 +59087,7 @@ fn __action1135< { let __start0 = __3.0; let __end0 = __5.2; - let __temp0 = __action329( + let __temp0 = __action334( source_code, mode, __3, @@ -58902,7 +59095,7 @@ fn __action1135< __5, ); let __temp0 = (__start0, __temp0, __end0); - __action947( + __action950( source_code, mode, __0, @@ -58914,7 +59107,7 @@ fn __action1135< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1136< +fn __action1139< >( source_code: &str, mode: Mode, @@ -58933,7 +59126,7 @@ fn __action1136< { let __start0 = __7.0; let __end0 = __9.2; - let __temp0 = __action1134( + let __temp0 = __action1137( source_code, mode, __7, @@ -58941,7 +59134,7 @@ fn __action1136< __9, ); let __temp0 = (__start0, __temp0, __end0); - __action1128( + __action1131( source_code, mode, __0, @@ -58958,7 +59151,7 @@ fn __action1136< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1137< +fn __action1140< >( source_code: &str, mode: Mode, @@ -58974,14 +59167,14 @@ fn __action1137< { let __start0 = __6.2; let __end0 = __7.0; - let __temp0 = __action328( + let __temp0 = __action333( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1128( + __action1131( source_code, mode, __0, @@ -58998,7 +59191,7 @@ fn __action1137< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1138< +fn __action1141< >( source_code: &str, mode: Mode, @@ -59014,7 +59207,7 @@ fn __action1138< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1134( + let __temp0 = __action1137( source_code, mode, __4, @@ -59022,7 +59215,7 @@ fn __action1138< __6, ); let __temp0 = (__start0, __temp0, __end0); - __action1129( + __action1132( source_code, mode, __0, @@ -59036,7 +59229,7 @@ fn __action1138< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1139< +fn __action1142< >( source_code: &str, mode: Mode, @@ -59049,14 +59242,14 @@ fn __action1139< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action328( + let __temp0 = __action333( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1129( + __action1132( source_code, mode, __0, @@ -59070,7 +59263,7 @@ fn __action1139< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1140< +fn __action1143< >( source_code: &str, mode: Mode, @@ -59089,7 +59282,7 @@ fn __action1140< { let __start0 = __7.0; let __end0 = __9.2; - let __temp0 = __action1134( + let __temp0 = __action1137( source_code, mode, __7, @@ -59097,7 +59290,7 @@ fn __action1140< __9, ); let __temp0 = (__start0, __temp0, __end0); - __action1130( + __action1133( source_code, mode, __0, @@ -59114,7 +59307,7 @@ fn __action1140< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1141< +fn __action1144< >( source_code: &str, mode: Mode, @@ -59130,14 +59323,14 @@ fn __action1141< { let __start0 = __6.2; let __end0 = __7.0; - let __temp0 = __action328( + let __temp0 = __action333( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1130( + __action1133( source_code, mode, __0, @@ -59154,7 +59347,7 @@ fn __action1141< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1142< +fn __action1145< >( source_code: &str, mode: Mode, @@ -59170,7 +59363,7 @@ fn __action1142< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1134( + let __temp0 = __action1137( source_code, mode, __4, @@ -59178,7 +59371,7 @@ fn __action1142< __6, ); let __temp0 = (__start0, __temp0, __end0); - __action1131( + __action1134( source_code, mode, __0, @@ -59192,7 +59385,7 @@ fn __action1142< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1143< +fn __action1146< >( source_code: &str, mode: Mode, @@ -59205,14 +59398,14 @@ fn __action1143< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action328( + let __temp0 = __action333( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1131( + __action1134( source_code, mode, __0, @@ -59226,24 +59419,24 @@ fn __action1143< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1144< +fn __action1147< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action395( + let __temp0 = __action398( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action393( + __action396( source_code, mode, __temp0, @@ -59252,27 +59445,27 @@ fn __action1144< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1145< +fn __action1148< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action1144( + let __temp0 = __action1147( source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action918( + __action919( source_code, mode, __0, @@ -59284,25 +59477,25 @@ fn __action1145< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1146< +fn __action1149< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action394( + let __temp0 = __action397( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action918( + __action919( source_code, mode, __0, @@ -59314,19 +59507,19 @@ fn __action1146< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1147< +fn __action1150< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), -) -> alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)> +) -> alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)> { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action720( + let __temp0 = __action723( source_code, mode, __0, @@ -59335,7 +59528,7 @@ fn __action1147< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action430( + __action433( source_code, mode, __temp0, @@ -59344,20 +59537,20 @@ fn __action1147< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1148< +fn __action1151< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), + __0: (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, ast::Suite, TextSize), -) -> alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)> +) -> alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)> { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action720( + let __temp0 = __action723( source_code, mode, __1, @@ -59366,7 +59559,7 @@ fn __action1148< __4, ); let __temp0 = (__start0, __temp0, __end0); - __action431( + __action434( source_code, mode, __0, @@ -59376,12 +59569,12 @@ fn __action1148< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1149< +fn __action1152< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), __4: (TextSize, core::option::Option<(TextSize, ast::Suite)>, TextSize), @@ -59389,14 +59582,14 @@ fn __action1149< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action340( + let __temp0 = __action345( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action826( + __action827( source_code, mode, __0, @@ -59410,27 +59603,27 @@ fn __action1149< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1150< +fn __action1153< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), - __4: (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), + __4: (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize), __5: (TextSize, core::option::Option<(TextSize, ast::Suite)>, TextSize), ) -> ast::Stmt { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action341( + let __temp0 = __action346( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action826( + __action827( source_code, mode, __0, @@ -59444,7 +59637,7 @@ fn __action1150< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1151< +fn __action1154< >( source_code: &str, mode: Mode, @@ -59455,7 +59648,7 @@ fn __action1151< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action721( + let __temp0 = __action724( source_code, mode, __0, @@ -59463,7 +59656,7 @@ fn __action1151< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action337( + __action342( source_code, mode, __temp0, @@ -59472,12 +59665,12 @@ fn __action1151< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1152< +fn __action1155< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -59487,7 +59680,7 @@ fn __action1152< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1151( + let __temp0 = __action1154( source_code, mode, __4, @@ -59495,7 +59688,7 @@ fn __action1152< __6, ); let __temp0 = (__start0, __temp0, __end0); - __action1149( + __action1152( source_code, mode, __0, @@ -59508,26 +59701,26 @@ fn __action1152< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1153< +fn __action1156< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action338( + let __temp0 = __action343( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1149( + __action1152( source_code, mode, __0, @@ -59540,15 +59733,15 @@ fn __action1153< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1154< +fn __action1157< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), - __4: (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), + __4: (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, ast::Suite, TextSize), @@ -59556,7 +59749,7 @@ fn __action1154< { let __start0 = __5.0; let __end0 = __7.2; - let __temp0 = __action1151( + let __temp0 = __action1154( source_code, mode, __5, @@ -59564,7 +59757,7 @@ fn __action1154< __7, ); let __temp0 = (__start0, __temp0, __end0); - __action1150( + __action1153( source_code, mode, __0, @@ -59578,27 +59771,27 @@ fn __action1154< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1155< +fn __action1158< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), - __4: (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), + __4: (TextSize, alloc::vec::Vec<(TextSize, crate::parser::ParenthesizedExpr, ast::Suite)>, TextSize), ) -> ast::Stmt { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action338( + let __temp0 = __action343( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1150( + __action1153( source_code, mode, __0, @@ -59612,24 +59805,24 @@ fn __action1155< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1156< +fn __action1159< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> alloc::vec::Vec +) -> alloc::vec::Vec { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action459( + let __temp0 = __action462( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action457( + __action460( source_code, mode, __temp0, @@ -59638,25 +59831,25 @@ fn __action1156< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1157< +fn __action1160< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> alloc::vec::Vec +) -> alloc::vec::Vec { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action459( + let __temp0 = __action462( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action458( + __action461( source_code, mode, __0, @@ -59666,7 +59859,7 @@ fn __action1157< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1158< +fn __action1161< >( source_code: &str, mode: Mode, @@ -59676,14 +59869,14 @@ fn __action1158< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action468( + let __temp0 = __action471( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action469( + __action472( source_code, mode, __temp0, @@ -59692,7 +59885,7 @@ fn __action1158< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1159< +fn __action1162< >( source_code: &str, mode: Mode, @@ -59703,14 +59896,14 @@ fn __action1159< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action468( + let __temp0 = __action471( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action470( + __action473( source_code, mode, __0, @@ -59720,7 +59913,7 @@ fn __action1159< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1160< +fn __action1163< >( source_code: &str, mode: Mode, @@ -59729,14 +59922,14 @@ fn __action1160< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action466( + let __temp0 = __action469( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action249( + __action252( source_code, mode, __temp0, @@ -59746,7 +59939,7 @@ fn __action1160< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1161< +fn __action1164< >( source_code: &str, mode: Mode, @@ -59756,13 +59949,13 @@ fn __action1161< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action467( + let __temp0 = __action470( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action249( + __action252( source_code, mode, __temp0, @@ -59772,24 +59965,24 @@ fn __action1161< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1162< +fn __action1165< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> alloc::vec::Vec +) -> alloc::vec::Vec { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action473( + let __temp0 = __action476( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action471( + __action474( source_code, mode, __temp0, @@ -59798,25 +59991,25 @@ fn __action1162< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1163< +fn __action1166< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> alloc::vec::Vec +) -> alloc::vec::Vec { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action473( + let __temp0 = __action476( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action472( + __action475( source_code, mode, __0, @@ -59826,24 +60019,24 @@ fn __action1163< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1164< +fn __action1167< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> core::option::Option> +) -> core::option::Option> { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action571( + let __temp0 = __action574( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action569( + __action572( source_code, mode, __temp0, @@ -59852,29 +60045,29 @@ fn __action1164< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1165< +fn __action1168< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1164( + let __temp0 = __action1167( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1081( + __action1084( source_code, mode, __0, @@ -59888,27 +60081,27 @@ fn __action1165< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1166< +fn __action1169< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action570( + let __temp0 = __action573( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1081( + __action1084( source_code, mode, __0, @@ -59922,30 +60115,30 @@ fn __action1166< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1167< +fn __action1170< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1164( + let __temp0 = __action1167( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1082( + __action1085( source_code, mode, __0, @@ -59960,28 +60153,28 @@ fn __action1167< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1168< +fn __action1171< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action570( + let __temp0 = __action573( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1082( + __action1085( source_code, mode, __0, @@ -59996,28 +60189,28 @@ fn __action1168< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1169< +fn __action1172< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1164( + let __temp0 = __action1167( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1083( + __action1086( source_code, mode, __0, @@ -60030,26 +60223,26 @@ fn __action1169< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1170< +fn __action1173< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action570( + let __temp0 = __action573( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1083( + __action1086( source_code, mode, __0, @@ -60062,29 +60255,29 @@ fn __action1170< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1171< +fn __action1174< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1164( + let __temp0 = __action1167( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1084( + __action1087( source_code, mode, __0, @@ -60098,27 +60291,27 @@ fn __action1171< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1172< +fn __action1175< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action570( + let __temp0 = __action573( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1084( + __action1087( source_code, mode, __0, @@ -60132,29 +60325,29 @@ fn __action1172< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1173< +fn __action1176< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1164( + let __temp0 = __action1167( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1085( + __action1088( source_code, mode, __0, @@ -60168,27 +60361,27 @@ fn __action1173< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1174< +fn __action1177< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action570( + let __temp0 = __action573( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1085( + __action1088( source_code, mode, __0, @@ -60202,30 +60395,30 @@ fn __action1174< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1175< +fn __action1178< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1164( + let __temp0 = __action1167( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1086( + __action1089( source_code, mode, __0, @@ -60240,28 +60433,28 @@ fn __action1175< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1176< +fn __action1179< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action570( + let __temp0 = __action573( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1086( + __action1089( source_code, mode, __0, @@ -60276,28 +60469,28 @@ fn __action1176< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1177< +fn __action1180< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1164( + let __temp0 = __action1167( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1087( + __action1090( source_code, mode, __0, @@ -60310,26 +60503,26 @@ fn __action1177< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1178< +fn __action1181< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action570( + let __temp0 = __action573( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1087( + __action1090( source_code, mode, __0, @@ -60342,29 +60535,29 @@ fn __action1178< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1179< +fn __action1182< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1164( + let __temp0 = __action1167( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1088( + __action1091( source_code, mode, __0, @@ -60378,27 +60571,27 @@ fn __action1179< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1180< +fn __action1183< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, TextSize, TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action570( + let __temp0 = __action573( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1088( + __action1091( source_code, mode, __0, @@ -60412,7 +60605,7 @@ fn __action1180< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1181< +fn __action1184< >( source_code: &str, mode: Mode, @@ -60422,14 +60615,14 @@ fn __action1181< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action356( + let __temp0 = __action359( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action354( + __action357( source_code, mode, __temp0, @@ -60438,7 +60631,7 @@ fn __action1181< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1182< +fn __action1185< >( source_code: &str, mode: Mode, @@ -60449,14 +60642,14 @@ fn __action1182< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action356( + let __temp0 = __action359( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action355( + __action358( source_code, mode, __0, @@ -60466,7 +60659,7 @@ fn __action1182< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1183< +fn __action1186< >( source_code: &str, mode: Mode, @@ -60475,14 +60668,14 @@ fn __action1183< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action428( + let __temp0 = __action431( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action353( + __action356( source_code, mode, __temp0, @@ -60492,7 +60685,7 @@ fn __action1183< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1184< +fn __action1187< >( source_code: &str, mode: Mode, @@ -60502,13 +60695,13 @@ fn __action1184< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action429( + let __temp0 = __action432( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action353( + __action356( source_code, mode, __temp0, @@ -60518,7 +60711,7 @@ fn __action1184< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1185< +fn __action1188< >( source_code: &str, mode: Mode, @@ -60528,14 +60721,14 @@ fn __action1185< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action409( + let __temp0 = __action412( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action417( + __action420( source_code, mode, __temp0, @@ -60544,7 +60737,7 @@ fn __action1185< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1186< +fn __action1189< >( source_code: &str, mode: Mode, @@ -60555,14 +60748,14 @@ fn __action1186< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action409( + let __temp0 = __action412( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action418( + __action421( source_code, mode, __0, @@ -60572,7 +60765,7 @@ fn __action1186< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1187< +fn __action1190< >( source_code: &str, mode: Mode, @@ -60584,14 +60777,14 @@ fn __action1187< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action407( + let __temp0 = __action410( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action668( + __action671( source_code, mode, __0, @@ -60604,7 +60797,7 @@ fn __action1187< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1188< +fn __action1191< >( source_code: &str, mode: Mode, @@ -60617,13 +60810,13 @@ fn __action1188< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action408( + let __temp0 = __action411( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action668( + __action671( source_code, mode, __0, @@ -60636,7 +60829,7 @@ fn __action1188< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1189< +fn __action1192< >( source_code: &str, mode: Mode, @@ -60647,14 +60840,14 @@ fn __action1189< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action407( + let __temp0 = __action410( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action669( + __action672( source_code, mode, __0, @@ -60666,7 +60859,7 @@ fn __action1189< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1190< +fn __action1193< >( source_code: &str, mode: Mode, @@ -60678,13 +60871,13 @@ fn __action1190< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action408( + let __temp0 = __action411( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action669( + __action672( source_code, mode, __0, @@ -60696,7 +60889,7 @@ fn __action1190< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1191< +fn __action1194< >( source_code: &str, mode: Mode, @@ -60707,14 +60900,14 @@ fn __action1191< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action407( + let __temp0 = __action410( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action670( + __action673( source_code, mode, __temp0, @@ -60726,7 +60919,7 @@ fn __action1191< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1192< +fn __action1195< >( source_code: &str, mode: Mode, @@ -60738,13 +60931,13 @@ fn __action1192< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action408( + let __temp0 = __action411( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action670( + __action673( source_code, mode, __temp0, @@ -60756,7 +60949,7 @@ fn __action1192< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1193< +fn __action1196< >( source_code: &str, mode: Mode, @@ -60766,14 +60959,14 @@ fn __action1193< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action407( + let __temp0 = __action410( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action671( + __action674( source_code, mode, __temp0, @@ -60784,7 +60977,7 @@ fn __action1193< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1194< +fn __action1197< >( source_code: &str, mode: Mode, @@ -60795,13 +60988,13 @@ fn __action1194< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action408( + let __temp0 = __action411( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action671( + __action674( source_code, mode, __temp0, @@ -60812,7 +61005,7 @@ fn __action1194< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1195< +fn __action1198< >( source_code: &str, mode: Mode, @@ -60824,14 +61017,14 @@ fn __action1195< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action407( + let __temp0 = __action410( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action672( + __action675( source_code, mode, __0, @@ -60844,7 +61037,7 @@ fn __action1195< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1196< +fn __action1199< >( source_code: &str, mode: Mode, @@ -60857,13 +61050,13 @@ fn __action1196< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action408( + let __temp0 = __action411( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action672( + __action675( source_code, mode, __0, @@ -60876,7 +61069,7 @@ fn __action1196< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1197< +fn __action1200< >( source_code: &str, mode: Mode, @@ -60887,14 +61080,14 @@ fn __action1197< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action407( + let __temp0 = __action410( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action673( + __action676( source_code, mode, __0, @@ -60906,7 +61099,7 @@ fn __action1197< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1198< +fn __action1201< >( source_code: &str, mode: Mode, @@ -60918,13 +61111,13 @@ fn __action1198< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action408( + let __temp0 = __action411( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action673( + __action676( source_code, mode, __0, @@ -60936,7 +61129,7 @@ fn __action1198< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1199< +fn __action1202< >( source_code: &str, mode: Mode, @@ -60947,14 +61140,14 @@ fn __action1199< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action407( + let __temp0 = __action410( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action674( + __action677( source_code, mode, __temp0, @@ -60966,7 +61159,7 @@ fn __action1199< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1200< +fn __action1203< >( source_code: &str, mode: Mode, @@ -60978,13 +61171,13 @@ fn __action1200< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action408( + let __temp0 = __action411( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action674( + __action677( source_code, mode, __temp0, @@ -60996,7 +61189,7 @@ fn __action1200< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1201< +fn __action1204< >( source_code: &str, mode: Mode, @@ -61006,14 +61199,14 @@ fn __action1201< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action407( + let __temp0 = __action410( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action675( + __action678( source_code, mode, __temp0, @@ -61024,7 +61217,7 @@ fn __action1201< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1202< +fn __action1205< >( source_code: &str, mode: Mode, @@ -61035,13 +61228,13 @@ fn __action1202< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action408( + let __temp0 = __action411( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action675( + __action678( source_code, mode, __temp0, @@ -61052,12 +61245,12 @@ fn __action1202< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1203< +fn __action1206< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Identifier, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -61066,7 +61259,7 @@ fn __action1203< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action324( + let __temp0 = __action329( source_code, mode, __1, @@ -61074,7 +61267,7 @@ fn __action1203< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action792( + __action793( source_code, mode, __0, @@ -61086,13 +61279,13 @@ fn __action1203< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1204< +fn __action1207< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, ast::Identifier, TextSize), __5: (TextSize, token::Tok, TextSize), @@ -61101,7 +61294,7 @@ fn __action1204< { let __start0 = __2.0; let __end0 = __4.2; - let __temp0 = __action324( + let __temp0 = __action329( source_code, mode, __2, @@ -61109,7 +61302,7 @@ fn __action1204< __4, ); let __temp0 = (__start0, __temp0, __end0); - __action794( + __action795( source_code, mode, __0, @@ -61122,23 +61315,23 @@ fn __action1204< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1205< +fn __action1208< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), ) -> Vec { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action160( + let __temp0 = __action161( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action321( + __action326( source_code, mode, __temp0, @@ -61148,25 +61341,25 @@ fn __action1205< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1206< +fn __action1209< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), ) -> Vec { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action160( + let __temp0 = __action161( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action664( + __action667( source_code, mode, __0, @@ -61178,24 +61371,24 @@ fn __action1206< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1207< +fn __action1210< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), ) -> Vec { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action160( + let __temp0 = __action161( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action665( + __action668( source_code, mode, __0, @@ -61206,24 +61399,24 @@ fn __action1207< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1208< +fn __action1211< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), ) -> core::option::Option> { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action1205( + let __temp0 = __action1208( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action319( + __action324( source_code, mode, __temp0, @@ -61232,12 +61425,12 @@ fn __action1208< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1209< +fn __action1212< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::WithItem, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -61246,14 +61439,14 @@ fn __action1209< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1208( + let __temp0 = __action1211( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1091( + __action1094( source_code, mode, __0, @@ -61266,7 +61459,7 @@ fn __action1209< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1210< +fn __action1213< >( source_code: &str, mode: Mode, @@ -61278,14 +61471,14 @@ fn __action1210< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action320( + let __temp0 = __action325( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1091( + __action1094( source_code, mode, __0, @@ -61298,12 +61491,12 @@ fn __action1210< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1211< +fn __action1214< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::WithItem, TextSize), __4: (TextSize, alloc::vec::Vec, TextSize), @@ -61313,14 +61506,14 @@ fn __action1211< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1208( + let __temp0 = __action1211( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1092( + __action1095( source_code, mode, __0, @@ -61334,7 +61527,7 @@ fn __action1211< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1212< +fn __action1215< >( source_code: &str, mode: Mode, @@ -61347,14 +61540,14 @@ fn __action1212< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action320( + let __temp0 = __action325( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1092( + __action1095( source_code, mode, __0, @@ -61368,12 +61561,12 @@ fn __action1212< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1213< +fn __action1216< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::WithItem, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -61381,14 +61574,14 @@ fn __action1213< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1208( + let __temp0 = __action1211( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1093( + __action1096( source_code, mode, __0, @@ -61400,7 +61593,7 @@ fn __action1213< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1214< +fn __action1217< >( source_code: &str, mode: Mode, @@ -61411,14 +61604,14 @@ fn __action1214< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action320( + let __temp0 = __action325( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1093( + __action1096( source_code, mode, __0, @@ -61430,12 +61623,12 @@ fn __action1214< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1215< +fn __action1218< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::WithItem, TextSize), __4: (TextSize, alloc::vec::Vec, TextSize), @@ -61444,14 +61637,14 @@ fn __action1215< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1208( + let __temp0 = __action1211( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1094( + __action1097( source_code, mode, __0, @@ -61464,7 +61657,7 @@ fn __action1215< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1216< +fn __action1219< >( source_code: &str, mode: Mode, @@ -61476,14 +61669,14 @@ fn __action1216< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action320( + let __temp0 = __action325( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1094( + __action1097( source_code, mode, __0, @@ -61496,24 +61689,24 @@ fn __action1216< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1217< +fn __action1220< >( source_code: &str, mode: Mode, __0: (TextSize, ast::CmpOp, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)> { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action516( + let __temp0 = __action519( source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action514( + __action517( source_code, mode, __temp0, @@ -61522,25 +61715,25 @@ fn __action1217< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1218< +fn __action1221< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), + __0: (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize), __1: (TextSize, ast::CmpOp, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)> { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action516( + let __temp0 = __action519( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action515( + __action518( source_code, mode, __0, @@ -61550,7 +61743,7 @@ fn __action1218< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1219< +fn __action1222< >( source_code: &str, mode: Mode, @@ -61559,13 +61752,13 @@ fn __action1219< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action363( + let __temp0 = __action366( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action361( + __action364( source_code, mode, __temp0, @@ -61574,7 +61767,7 @@ fn __action1219< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1220< +fn __action1223< >( source_code: &str, mode: Mode, @@ -61587,13 +61780,13 @@ fn __action1220< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action1219( + let __temp0 = __action1222( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action856( + __action857( source_code, mode, __0, @@ -61606,7 +61799,7 @@ fn __action1220< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1221< +fn __action1224< >( source_code: &str, mode: Mode, @@ -61618,14 +61811,14 @@ fn __action1221< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action362( + let __temp0 = __action365( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action856( + __action857( source_code, mode, __0, @@ -61638,7 +61831,7 @@ fn __action1221< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1222< +fn __action1225< >( source_code: &str, mode: Mode, @@ -61647,13 +61840,13 @@ fn __action1222< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action296( + let __temp0 = __action301( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action294( + __action299( source_code, mode, __temp0, @@ -61662,7 +61855,7 @@ fn __action1222< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1223< +fn __action1226< >( source_code: &str, mode: Mode, @@ -61674,13 +61867,13 @@ fn __action1223< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1222( + let __temp0 = __action1225( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action903( + __action904( source_code, mode, __0, @@ -61692,7 +61885,7 @@ fn __action1223< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1224< +fn __action1227< >( source_code: &str, mode: Mode, @@ -61703,14 +61896,14 @@ fn __action1224< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action295( + let __temp0 = __action300( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action903( + __action904( source_code, mode, __0, @@ -61722,25 +61915,25 @@ fn __action1224< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1225< +fn __action1228< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action722( + __action725( source_code, mode, __0, @@ -61752,25 +61945,25 @@ fn __action1225< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1226< +fn __action1229< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action723( + __action726( source_code, mode, __0, @@ -61782,25 +61975,25 @@ fn __action1226< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1227< +fn __action1230< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action724( + __action727( source_code, mode, __0, @@ -61812,24 +62005,24 @@ fn __action1227< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1228< +fn __action1231< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action725( + __action728( source_code, mode, __0, @@ -61840,24 +62033,24 @@ fn __action1228< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1229< +fn __action1232< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action726( + __action729( source_code, mode, __0, @@ -61868,7 +62061,7 @@ fn __action1229< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1230< +fn __action1233< >( source_code: &str, mode: Mode, @@ -61879,14 +62072,14 @@ fn __action1230< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action727( + __action730( source_code, mode, __0, @@ -61898,25 +62091,25 @@ fn __action1230< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1231< +fn __action1234< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action728( + __action731( source_code, mode, __0, @@ -61928,25 +62121,25 @@ fn __action1231< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1232< +fn __action1235< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action729( + __action732( source_code, mode, __0, @@ -61958,7 +62151,7 @@ fn __action1232< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1233< +fn __action1236< >( source_code: &str, mode: Mode, @@ -61969,14 +62162,14 @@ fn __action1233< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action730( + __action733( source_code, mode, __0, @@ -61988,26 +62181,26 @@ fn __action1233< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1234< +fn __action1237< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1077( + __action1080( source_code, mode, __0, @@ -62020,24 +62213,24 @@ fn __action1234< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1235< +fn __action1238< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1078( + __action1081( source_code, mode, __0, @@ -62048,49 +62241,23 @@ fn __action1235< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1236< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), -) -> Result> -{ - let __start0 = __0.2; - let __end0 = __0.2; - let __temp0 = __action413( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action732( - source_code, - mode, - __0, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1237< +fn __action1239< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Number, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action733( + __action735( source_code, mode, __0, @@ -62100,23 +62267,23 @@ fn __action1237< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1238< +fn __action1240< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action734( + __action736( source_code, mode, __0, @@ -62126,25 +62293,25 @@ fn __action1238< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1239< +fn __action1241< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), + __1: (TextSize, core::option::Option>, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action735( + __action737( source_code, mode, __0, @@ -62156,26 +62323,26 @@ fn __action1239< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1240< +fn __action1242< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action736( + __action738( source_code, mode, __0, @@ -62188,26 +62355,26 @@ fn __action1240< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1241< +fn __action1243< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action737( + __action739( source_code, mode, __0, @@ -62220,25 +62387,25 @@ fn __action1241< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1242< +fn __action1244< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action738( + __action740( source_code, mode, __0, @@ -62250,28 +62417,28 @@ fn __action1242< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1243< +fn __action1245< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1165( + __action1168( source_code, mode, __0, @@ -62286,26 +62453,26 @@ fn __action1243< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1244< +fn __action1246< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1166( + __action1169( source_code, mode, __0, @@ -62318,29 +62485,29 @@ fn __action1244< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1245< +fn __action1247< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1167( + __action1170( source_code, mode, __0, @@ -62356,27 +62523,27 @@ fn __action1245< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1246< +fn __action1248< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1168( + __action1171( source_code, mode, __0, @@ -62390,27 +62557,27 @@ fn __action1246< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1247< +fn __action1249< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1169( + __action1172( source_code, mode, __0, @@ -62424,25 +62591,25 @@ fn __action1247< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1248< +fn __action1250< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1170( + __action1173( source_code, mode, __0, @@ -62454,28 +62621,28 @@ fn __action1248< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1249< +fn __action1251< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1171( + __action1174( source_code, mode, __0, @@ -62490,26 +62657,26 @@ fn __action1249< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1250< +fn __action1252< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1172( + __action1175( source_code, mode, __0, @@ -62522,24 +62689,24 @@ fn __action1250< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1251< +fn __action1253< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action741( + __action743( source_code, mode, __0, @@ -62550,25 +62717,25 @@ fn __action1251< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1252< +fn __action1254< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action742( + __action744( source_code, mode, __0, @@ -62580,26 +62747,26 @@ fn __action1252< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1253< +fn __action1255< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action743( + __action745( source_code, mode, __0, @@ -62612,26 +62779,26 @@ fn __action1253< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1254< +fn __action1256< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action744( + __action746( source_code, mode, __0, @@ -62644,25 +62811,25 @@ fn __action1254< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1255< +fn __action1257< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), + __1: (TextSize, core::option::Option>, crate::parser::ParenthesizedExpr)>>, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action745( + __action747( source_code, mode, __0, @@ -62674,26 +62841,26 @@ fn __action1255< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1256< +fn __action1258< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), + __1: (TextSize, (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr), TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action746( + __action748( source_code, mode, __0, @@ -62706,25 +62873,25 @@ fn __action1256< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1257< +fn __action1259< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action747( + __action749( source_code, mode, __0, @@ -62736,26 +62903,26 @@ fn __action1257< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1258< +fn __action1260< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action748( + __action750( source_code, mode, __0, @@ -62766,58 +62933,6 @@ fn __action1258< ) } -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1259< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr -{ - let __start0 = __0.2; - let __end0 = __0.2; - let __temp0 = __action413( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action749( - source_code, - mode, - __0, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1260< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr -{ - let __start0 = __0.2; - let __end0 = __0.2; - let __temp0 = __action413( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action750( - source_code, - mode, - __0, - __temp0, - ) -} - #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] fn __action1261< @@ -62825,11 +62940,11 @@ fn __action1261< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, @@ -62851,11 +62966,11 @@ fn __action1262< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, @@ -62876,12 +62991,12 @@ fn __action1263< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), -) -> Result> + __0: (TextSize, token::Tok, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, @@ -62902,12 +63017,12 @@ fn __action1264< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::Number, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, token::Tok, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, @@ -62928,12 +63043,12 @@ fn __action1265< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::Identifier, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, ast::Number, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, @@ -62951,24 +63066,50 @@ fn __action1265< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] fn __action1266< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, ast::Identifier, TextSize), +) -> crate::parser::ParenthesizedExpr +{ + let __start0 = __0.2; + let __end0 = __0.2; + let __temp0 = __action416( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action756( + source_code, + mode, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1267< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, TextSize), + __1: (TextSize, core::option::Option>, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action756( + __action757( source_code, mode, __0, @@ -62980,26 +63121,26 @@ fn __action1266< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1267< +fn __action1268< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action757( + __action758( source_code, mode, __0, @@ -63012,28 +63153,28 @@ fn __action1267< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1268< +fn __action1269< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1173( + __action1176( source_code, mode, __0, @@ -63048,26 +63189,26 @@ fn __action1268< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1269< +fn __action1270< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1174( + __action1177( source_code, mode, __0, @@ -63080,29 +63221,29 @@ fn __action1269< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1270< +fn __action1271< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1175( + __action1178( source_code, mode, __0, @@ -63118,27 +63259,27 @@ fn __action1270< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1271< +fn __action1272< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1176( + __action1179( source_code, mode, __0, @@ -63152,27 +63293,27 @@ fn __action1271< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1272< +fn __action1273< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1177( + __action1180( source_code, mode, __0, @@ -63186,25 +63327,25 @@ fn __action1272< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1273< +fn __action1274< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1178( + __action1181( source_code, mode, __0, @@ -63216,28 +63357,28 @@ fn __action1273< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1274< +fn __action1275< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), __5: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1179( + __action1182( source_code, mode, __0, @@ -63252,26 +63393,26 @@ fn __action1274< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1275< +fn __action1276< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1180( + __action1183( source_code, mode, __0, @@ -63284,24 +63425,24 @@ fn __action1275< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1276< +fn __action1277< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action760( + __action761( source_code, mode, __0, @@ -63312,25 +63453,25 @@ fn __action1276< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1277< +fn __action1278< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action761( + __action762( source_code, mode, __0, @@ -63342,26 +63483,26 @@ fn __action1277< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1278< +fn __action1279< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action762( + __action763( source_code, mode, __0, @@ -63374,26 +63515,26 @@ fn __action1278< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1279< +fn __action1280< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action763( + __action764( source_code, mode, __0, @@ -63406,25 +63547,25 @@ fn __action1279< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1280< +fn __action1281< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), + __1: (TextSize, core::option::Option>, crate::parser::ParenthesizedExpr)>>, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action764( + __action765( source_code, mode, __0, @@ -63436,26 +63577,26 @@ fn __action1280< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1281< +fn __action1282< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), + __1: (TextSize, (crate::parser::ParenthesizedExpr, crate::parser::ParenthesizedExpr), TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action765( + __action766( source_code, mode, __0, @@ -63468,25 +63609,25 @@ fn __action1281< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1282< +fn __action1283< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action766( + __action767( source_code, mode, __0, @@ -63498,26 +63639,26 @@ fn __action1282< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1283< +fn __action1284< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, Vec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action767( + __action768( source_code, mode, __0, @@ -63530,23 +63671,23 @@ fn __action1283< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1284< +fn __action1285< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action768( + __action769( source_code, mode, __0, @@ -63556,23 +63697,23 @@ fn __action1284< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1285< +fn __action1286< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action769( + __action770( source_code, mode, __0, @@ -63582,23 +63723,23 @@ fn __action1285< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1286< +fn __action1287< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action770( + __action771( source_code, mode, __0, @@ -63608,23 +63749,23 @@ fn __action1286< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1287< +fn __action1288< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action771( + __action772( source_code, mode, __0, @@ -63634,24 +63775,24 @@ fn __action1287< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1288< +fn __action1289< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Arguments, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action772( + __action773( source_code, mode, __0, @@ -63662,26 +63803,26 @@ fn __action1288< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1289< +fn __action1290< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action773( + __action774( source_code, mode, __0, @@ -63694,25 +63835,25 @@ fn __action1289< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1290< +fn __action1291< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, ast::Identifier, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action774( + __action775( source_code, mode, __0, @@ -63724,24 +63865,24 @@ fn __action1290< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1291< +fn __action1292< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Arguments, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action775( + __action776( source_code, mode, __0, @@ -63752,26 +63893,26 @@ fn __action1291< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1292< +fn __action1293< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action776( + __action777( source_code, mode, __0, @@ -63784,25 +63925,25 @@ fn __action1292< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1293< +fn __action1294< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, ast::Identifier, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action777( + __action778( source_code, mode, __0, @@ -63814,24 +63955,24 @@ fn __action1293< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1294< +fn __action1295< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action778( + __action779( source_code, mode, __0, @@ -63842,24 +63983,24 @@ fn __action1294< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1295< +fn __action1296< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action779( + __action780( source_code, mode, __0, @@ -63870,7 +64011,7 @@ fn __action1295< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1296< +fn __action1297< >( source_code: &str, mode: Mode, @@ -63879,14 +64020,14 @@ fn __action1296< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action780( + __action781( source_code, mode, __0, @@ -63896,7 +64037,7 @@ fn __action1296< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1297< +fn __action1298< >( source_code: &str, mode: Mode, @@ -63906,14 +64047,14 @@ fn __action1297< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action782( + __action783( source_code, mode, __0, @@ -63924,7 +64065,7 @@ fn __action1297< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1298< +fn __action1299< >( source_code: &str, mode: Mode, @@ -63934,14 +64075,14 @@ fn __action1298< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action783( + __action784( source_code, mode, __0, @@ -63952,24 +64093,24 @@ fn __action1298< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1299< +fn __action1300< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action784( + __action785( source_code, mode, __0, @@ -63980,24 +64121,24 @@ fn __action1299< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1300< +fn __action1301< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, crate::parser::ParenthesizedExpr)>, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action785( + __action786( source_code, mode, __0, @@ -64008,25 +64149,25 @@ fn __action1300< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1301< +fn __action1302< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), ) -> ast::Decorator { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action786( + __action787( source_code, mode, __0, @@ -64038,24 +64179,24 @@ fn __action1301< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1302< +fn __action1303< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action787( + __action788( source_code, mode, __0, @@ -64066,7 +64207,7 @@ fn __action1302< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1303< +fn __action1304< >( source_code: &str, mode: Mode, @@ -64075,14 +64216,14 @@ fn __action1303< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action788( + __action789( source_code, mode, __0, @@ -64092,7 +64233,7 @@ fn __action1303< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1304< +fn __action1305< >( source_code: &str, mode: Mode, @@ -64102,14 +64243,14 @@ fn __action1304< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action789( + __action790( source_code, mode, __0, @@ -64120,25 +64261,25 @@ fn __action1304< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1305< +fn __action1306< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Parameter { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1103( + __action1106( source_code, mode, __0, @@ -64150,7 +64291,7 @@ fn __action1305< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1306< +fn __action1307< >( source_code: &str, mode: Mode, @@ -64159,14 +64300,14 @@ fn __action1306< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1104( + __action1107( source_code, mode, __0, @@ -64176,25 +64317,25 @@ fn __action1306< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1307< +fn __action1308< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action795( + __action796( source_code, mode, __0, @@ -64206,25 +64347,25 @@ fn __action1307< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1308< +fn __action1309< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action796( + __action797( source_code, mode, __0, @@ -64236,24 +64377,24 @@ fn __action1308< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1309< +fn __action1310< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), ) -> Result> { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action797( + __action798( source_code, mode, __0, @@ -64264,25 +64405,25 @@ fn __action1309< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1310< +fn __action1311< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action798( + __action799( source_code, mode, __0, @@ -64294,26 +64435,26 @@ fn __action1310< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1311< +fn __action1312< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, core::option::Option, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, core::option::Option, TextSize), ) -> Result> { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action799( + __action800( source_code, mode, __0, @@ -64326,25 +64467,25 @@ fn __action1311< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1312< +fn __action1313< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), __2: (TextSize, token::Tok, TextSize), ) -> StringType { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action801( + __action802( source_code, mode, __0, @@ -64356,23 +64497,23 @@ fn __action1312< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1313< +fn __action1314< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), -) -> ast::Expr + __0: (TextSize, alloc::vec::Vec, TextSize), +) -> ast::FStringFormatSpec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action802( + __action803( source_code, mode, __0, @@ -64382,28 +64523,54 @@ fn __action1313< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1314< +fn __action1315< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, (String, bool), TextSize), +) -> Result> +{ + let __start0 = __0.2; + let __end0 = __0.2; + let __temp0 = __action416( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action804( + source_code, + mode, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1316< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), - __4: (TextSize, core::option::Option, TextSize), + __4: (TextSize, core::option::Option, TextSize), __5: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action804( + __action805( source_code, mode, __0, @@ -64418,27 +64585,27 @@ fn __action1314< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1315< +fn __action1317< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), - __3: (TextSize, core::option::Option, TextSize), + __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action805( + __action806( source_code, mode, __0, @@ -64452,24 +64619,24 @@ fn __action1315< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1316< +fn __action1318< >( source_code: &str, mode: Mode, __0: (TextSize, ast::UnaryOp, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action806( + __action807( source_code, mode, __0, @@ -64480,24 +64647,24 @@ fn __action1316< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1317< +fn __action1319< >( source_code: &str, mode: Mode, __0: (TextSize, ast::UnaryOp, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action807( + __action808( source_code, mode, __0, @@ -64508,7 +64675,7 @@ fn __action1317< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1318< +fn __action1320< >( source_code: &str, mode: Mode, @@ -64517,14 +64684,14 @@ fn __action1318< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action808( + __action809( source_code, mode, __0, @@ -64534,7 +64701,7 @@ fn __action1318< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1319< +fn __action1321< >( source_code: &str, mode: Mode, @@ -64543,14 +64710,14 @@ fn __action1319< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action809( + __action810( source_code, mode, __0, @@ -64560,24 +64727,24 @@ fn __action1319< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1320< +fn __action1322< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option, TextSize), + __1: (TextSize, core::option::Option, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action810( + __action811( source_code, mode, __0, @@ -64588,23 +64755,23 @@ fn __action1320< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1321< +fn __action1323< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action811( + __action812( source_code, mode, __0, @@ -64614,24 +64781,24 @@ fn __action1321< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1322< +fn __action1324< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, core::option::Option>, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action816( + __action817( source_code, mode, __0, @@ -64642,25 +64809,25 @@ fn __action1322< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1323< +fn __action1325< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action817( + __action818( source_code, mode, __0, @@ -64672,24 +64839,24 @@ fn __action1323< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1324< +fn __action1326< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action818( + __action819( source_code, mode, __0, @@ -64700,24 +64867,24 @@ fn __action1324< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1325< +fn __action1327< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action819( + __action820( source_code, mode, __0, @@ -64728,24 +64895,24 @@ fn __action1325< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1326< +fn __action1328< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action820( + __action821( source_code, mode, __0, @@ -64756,23 +64923,23 @@ fn __action1326< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1327< +fn __action1329< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, Vec, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action821( + __action822( source_code, mode, __0, @@ -64782,24 +64949,24 @@ fn __action1327< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1328< +fn __action1330< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action822( + __action823( source_code, mode, __0, @@ -64810,23 +64977,23 @@ fn __action1328< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1329< +fn __action1331< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, Vec, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action823( + __action824( source_code, mode, __0, @@ -64836,7 +65003,7 @@ fn __action1329< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1330< +fn __action1332< >( source_code: &str, mode: Mode, @@ -64846,14 +65013,14 @@ fn __action1330< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action824( + __action825( source_code, mode, __0, @@ -64864,7 +65031,7 @@ fn __action1330< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1331< +fn __action1333< >( source_code: &str, mode: Mode, @@ -64873,14 +65040,14 @@ fn __action1331< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action825( + __action826( source_code, mode, __0, @@ -64890,7 +65057,7 @@ fn __action1331< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1332< +fn __action1334< >( source_code: &str, mode: Mode, @@ -64901,14 +65068,14 @@ fn __action1332< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1119( + __action1122( source_code, mode, __0, @@ -64920,7 +65087,7 @@ fn __action1332< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1333< +fn __action1335< >( source_code: &str, mode: Mode, @@ -64929,14 +65096,14 @@ fn __action1333< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1120( + __action1123( source_code, mode, __0, @@ -64946,7 +65113,7 @@ fn __action1333< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1334< +fn __action1336< >( source_code: &str, mode: Mode, @@ -64957,14 +65124,14 @@ fn __action1334< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1121( + __action1124( source_code, mode, __0, @@ -64976,7 +65143,7 @@ fn __action1334< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1335< +fn __action1337< >( source_code: &str, mode: Mode, @@ -64985,14 +65152,14 @@ fn __action1335< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1122( + __action1125( source_code, mode, __0, @@ -65002,7 +65169,7 @@ fn __action1335< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1336< +fn __action1338< >( source_code: &str, mode: Mode, @@ -65011,14 +65178,14 @@ fn __action1336< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action829( + __action830( source_code, mode, __0, @@ -65028,7 +65195,7 @@ fn __action1336< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1337< +fn __action1339< >( source_code: &str, mode: Mode, @@ -65040,14 +65207,14 @@ fn __action1337< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action830( + __action831( source_code, mode, __0, @@ -65060,7 +65227,7 @@ fn __action1337< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1338< +fn __action1340< >( source_code: &str, mode: Mode, @@ -65071,14 +65238,14 @@ fn __action1338< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action831( + __action832( source_code, mode, __0, @@ -65090,7 +65257,7 @@ fn __action1338< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1339< +fn __action1341< >( source_code: &str, mode: Mode, @@ -65099,14 +65266,14 @@ fn __action1339< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action832( + __action833( source_code, mode, __0, @@ -65116,7 +65283,7 @@ fn __action1339< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1340< +fn __action1342< >( source_code: &str, mode: Mode, @@ -65126,14 +65293,14 @@ fn __action1340< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action833( + __action834( source_code, mode, __0, @@ -65144,7 +65311,7 @@ fn __action1340< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1341< +fn __action1343< >( source_code: &str, mode: Mode, @@ -65156,14 +65323,14 @@ fn __action1341< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action834( + __action835( source_code, mode, __0, @@ -65176,23 +65343,23 @@ fn __action1341< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1342< +fn __action1344< >( source_code: &str, mode: Mode, __0: (TextSize, (IpyEscapeKind, String), TextSize), -) -> Result> +) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action835( + __action836( source_code, mode, __0, @@ -65202,7 +65369,7 @@ fn __action1342< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1343< +fn __action1345< >( source_code: &str, mode: Mode, @@ -65211,14 +65378,14 @@ fn __action1343< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action836( + __action837( source_code, mode, __0, @@ -65228,24 +65395,24 @@ fn __action1343< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1344< +fn __action1346< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), ) -> Result> { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action837( + __action838( source_code, mode, __0, @@ -65256,7 +65423,7 @@ fn __action1344< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1345< +fn __action1347< >( source_code: &str, mode: Mode, @@ -65264,28 +65431,28 @@ fn __action1345< __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, core::option::Option<(String, bool)>, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Result> + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Result> { let __start0 = __1.2; let __end0 = __2.0; let __start1 = __4.2; let __end1 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action413( + let __temp1 = __action416( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action838( + __action839( source_code, mode, __0, @@ -65300,7 +65467,7 @@ fn __action1345< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1346< +fn __action1348< >( source_code: &str, mode: Mode, @@ -65309,14 +65476,14 @@ fn __action1346< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action839( + __action840( source_code, mode, __0, @@ -65326,7 +65493,7 @@ fn __action1346< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1347< +fn __action1349< >( source_code: &str, mode: Mode, @@ -65335,14 +65502,14 @@ fn __action1347< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action840( + __action841( source_code, mode, __0, @@ -65352,7 +65519,7 @@ fn __action1347< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1348< +fn __action1350< >( source_code: &str, mode: Mode, @@ -65361,14 +65528,14 @@ fn __action1348< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action841( + __action842( source_code, mode, __0, @@ -65378,23 +65545,23 @@ fn __action1348< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1349< +fn __action1351< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action842( + __action843( source_code, mode, __0, @@ -65404,23 +65571,23 @@ fn __action1349< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1350< +fn __action1352< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action843( + __action844( source_code, mode, __0, @@ -65430,23 +65597,23 @@ fn __action1350< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1351< +fn __action1353< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), -) -> Result> + __0: (TextSize, StringType, TextSize), +) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action844( + __action845( source_code, mode, __0, @@ -65456,23 +65623,23 @@ fn __action1351< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1352< +fn __action1354< >( source_code: &str, mode: Mode, - __0: (TextSize, token::Tok, TextSize), -) -> ast::Expr + __0: (TextSize, Vec, TextSize), +) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action845( + __action846( source_code, mode, __0, @@ -65482,7 +65649,7 @@ fn __action1352< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1353< +fn __action1355< >( source_code: &str, mode: Mode, @@ -65491,14 +65658,14 @@ fn __action1353< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action846( + __action847( source_code, mode, __0, @@ -65508,7 +65675,7 @@ fn __action1353< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1354< +fn __action1356< >( source_code: &str, mode: Mode, @@ -65517,14 +65684,14 @@ fn __action1354< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action847( + __action848( source_code, mode, __0, @@ -65534,23 +65701,23 @@ fn __action1354< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1355< +fn __action1357< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), -) -> Result> + __0: (TextSize, token::Tok, TextSize), +) -> ast::Expr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action848( + __action849( source_code, mode, __0, @@ -65560,7 +65727,7 @@ fn __action1355< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1356< +fn __action1358< >( source_code: &str, mode: Mode, @@ -65570,14 +65737,14 @@ fn __action1356< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action849( + __action850( source_code, mode, __0, @@ -65588,7 +65755,7 @@ fn __action1356< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1357< +fn __action1359< >( source_code: &str, mode: Mode, @@ -65600,14 +65767,14 @@ fn __action1357< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action850( + __action851( source_code, mode, __0, @@ -65620,7 +65787,7 @@ fn __action1357< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1358< +fn __action1360< >( source_code: &str, mode: Mode, @@ -65631,14 +65798,14 @@ fn __action1358< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action851( + __action852( source_code, mode, __0, @@ -65650,7 +65817,7 @@ fn __action1358< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1359< +fn __action1361< >( source_code: &str, mode: Mode, @@ -65663,14 +65830,14 @@ fn __action1359< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action852( + __action853( source_code, mode, __0, @@ -65684,7 +65851,7 @@ fn __action1359< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1360< +fn __action1362< >( source_code: &str, mode: Mode, @@ -65696,14 +65863,14 @@ fn __action1360< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action853( + __action854( source_code, mode, __0, @@ -65716,7 +65883,7 @@ fn __action1360< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1361< +fn __action1363< >( source_code: &str, mode: Mode, @@ -65731,14 +65898,14 @@ fn __action1361< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action854( + __action855( source_code, mode, __0, @@ -65754,7 +65921,7 @@ fn __action1361< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1362< +fn __action1364< >( source_code: &str, mode: Mode, @@ -65768,14 +65935,14 @@ fn __action1362< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action855( + __action856( source_code, mode, __0, @@ -65790,7 +65957,7 @@ fn __action1362< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1363< +fn __action1365< >( source_code: &str, mode: Mode, @@ -65801,14 +65968,14 @@ fn __action1363< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action857( + __action858( source_code, mode, __0, @@ -65820,7 +65987,7 @@ fn __action1363< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1364< +fn __action1366< >( source_code: &str, mode: Mode, @@ -65829,14 +65996,14 @@ fn __action1364< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action858( + __action859( source_code, mode, __0, @@ -65846,7 +66013,7 @@ fn __action1364< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1365< +fn __action1367< >( source_code: &str, mode: Mode, @@ -65857,14 +66024,14 @@ fn __action1365< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action859( + __action860( source_code, mode, __0, @@ -65876,7 +66043,7 @@ fn __action1365< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1366< +fn __action1368< >( source_code: &str, mode: Mode, @@ -65887,14 +66054,14 @@ fn __action1366< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action860( + __action861( source_code, mode, __0, @@ -65906,12 +66073,12 @@ fn __action1366< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1367< +fn __action1369< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -65922,14 +66089,14 @@ fn __action1367< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action862( + __action863( source_code, mode, __0, @@ -65946,12 +66113,12 @@ fn __action1367< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1368< +fn __action1370< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -65962,14 +66129,14 @@ fn __action1368< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action863( + __action864( source_code, mode, __0, @@ -65986,12 +66153,12 @@ fn __action1368< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1369< +fn __action1371< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), @@ -66001,14 +66168,14 @@ fn __action1369< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action864( + __action865( source_code, mode, __0, @@ -66024,25 +66191,25 @@ fn __action1369< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1370< +fn __action1372< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action865( + __action866( source_code, mode, __0, @@ -66054,23 +66221,23 @@ fn __action1370< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1371< +fn __action1373< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action866( + __action867( source_code, mode, __0, @@ -66080,7 +66247,7 @@ fn __action1371< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1372< +fn __action1374< >( source_code: &str, mode: Mode, @@ -66090,14 +66257,14 @@ fn __action1372< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action867( + __action868( source_code, mode, __0, @@ -66108,24 +66275,24 @@ fn __action1372< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1373< +fn __action1375< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action868( + __action869( source_code, mode, __0, @@ -66136,24 +66303,24 @@ fn __action1373< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1374< +fn __action1376< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action869( + __action870( source_code, mode, __0, @@ -66164,23 +66331,23 @@ fn __action1374< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1375< +fn __action1377< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Number, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action870( + __action871( source_code, mode, __0, @@ -66190,24 +66357,24 @@ fn __action1375< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1376< +fn __action1378< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action871( + __action872( source_code, mode, __0, @@ -66218,7 +66385,7 @@ fn __action1376< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1377< +fn __action1379< >( source_code: &str, mode: Mode, @@ -66227,14 +66394,14 @@ fn __action1377< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action872( + __action873( source_code, mode, __0, @@ -66244,24 +66411,24 @@ fn __action1377< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1378< +fn __action1380< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action873( + __action874( source_code, mode, __0, @@ -66272,24 +66439,24 @@ fn __action1378< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1379< +fn __action1381< >( source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action874( + __action875( source_code, mode, __0, @@ -66300,25 +66467,25 @@ fn __action1379< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1380< +fn __action1382< >( source_code: &str, mode: Mode, __0: (TextSize, ast::ParameterWithDefault, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::ParameterWithDefault { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action495( + __action498( source_code, mode, __0, @@ -66330,25 +66497,25 @@ fn __action1380< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1381< +fn __action1383< >( source_code: &str, mode: Mode, __0: (TextSize, ast::ParameterWithDefault, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::ParameterWithDefault { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action484( + __action487( source_code, mode, __0, @@ -66360,7 +66527,7 @@ fn __action1381< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1382< +fn __action1384< >( source_code: &str, mode: Mode, @@ -66375,14 +66542,14 @@ fn __action1382< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action998( + __action1001( source_code, mode, __0, @@ -66398,7 +66565,7 @@ fn __action1382< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1383< +fn __action1385< >( source_code: &str, mode: Mode, @@ -66412,14 +66579,14 @@ fn __action1383< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action999( + __action1002( source_code, mode, __0, @@ -66434,7 +66601,7 @@ fn __action1383< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1384< +fn __action1386< >( source_code: &str, mode: Mode, @@ -66450,14 +66617,14 @@ fn __action1384< { let __start0 = __7.2; let __end0 = __7.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1000( + __action1003( source_code, mode, __0, @@ -66474,7 +66641,7 @@ fn __action1384< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1385< +fn __action1387< >( source_code: &str, mode: Mode, @@ -66489,14 +66656,14 @@ fn __action1385< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1001( + __action1004( source_code, mode, __0, @@ -66512,7 +66679,7 @@ fn __action1385< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1386< +fn __action1388< >( source_code: &str, mode: Mode, @@ -66525,14 +66692,14 @@ fn __action1386< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1002( + __action1005( source_code, mode, __0, @@ -66546,7 +66713,7 @@ fn __action1386< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1387< +fn __action1389< >( source_code: &str, mode: Mode, @@ -66558,14 +66725,14 @@ fn __action1387< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1003( + __action1006( source_code, mode, __0, @@ -66578,7 +66745,7 @@ fn __action1387< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1388< +fn __action1390< >( source_code: &str, mode: Mode, @@ -66592,14 +66759,14 @@ fn __action1388< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1004( + __action1007( source_code, mode, __0, @@ -66614,7 +66781,7 @@ fn __action1388< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1389< +fn __action1391< >( source_code: &str, mode: Mode, @@ -66627,14 +66794,14 @@ fn __action1389< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1005( + __action1008( source_code, mode, __0, @@ -66648,7 +66815,7 @@ fn __action1389< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1390< +fn __action1392< >( source_code: &str, mode: Mode, @@ -66658,14 +66825,14 @@ fn __action1390< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1006( + __action1009( source_code, mode, __0, @@ -66676,7 +66843,7 @@ fn __action1390< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1391< +fn __action1393< >( source_code: &str, mode: Mode, @@ -66690,14 +66857,14 @@ fn __action1391< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1007( + __action1010( source_code, mode, __0, @@ -66712,7 +66879,7 @@ fn __action1391< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1392< +fn __action1394< >( source_code: &str, mode: Mode, @@ -66725,14 +66892,14 @@ fn __action1392< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1008( + __action1011( source_code, mode, __0, @@ -66746,7 +66913,7 @@ fn __action1392< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1393< +fn __action1395< >( source_code: &str, mode: Mode, @@ -66761,14 +66928,14 @@ fn __action1393< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1009( + __action1012( source_code, mode, __0, @@ -66784,7 +66951,7 @@ fn __action1393< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1394< +fn __action1396< >( source_code: &str, mode: Mode, @@ -66798,14 +66965,14 @@ fn __action1394< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1010( + __action1013( source_code, mode, __0, @@ -66820,7 +66987,7 @@ fn __action1394< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1395< +fn __action1397< >( source_code: &str, mode: Mode, @@ -66832,14 +66999,14 @@ fn __action1395< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1011( + __action1014( source_code, mode, __0, @@ -66852,7 +67019,7 @@ fn __action1395< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1396< +fn __action1398< >( source_code: &str, mode: Mode, @@ -66863,14 +67030,14 @@ fn __action1396< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1012( + __action1015( source_code, mode, __0, @@ -66882,7 +67049,7 @@ fn __action1396< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1397< +fn __action1399< >( source_code: &str, mode: Mode, @@ -66895,14 +67062,14 @@ fn __action1397< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1013( + __action1016( source_code, mode, __0, @@ -66916,7 +67083,7 @@ fn __action1397< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1398< +fn __action1400< >( source_code: &str, mode: Mode, @@ -66928,14 +67095,14 @@ fn __action1398< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1014( + __action1017( source_code, mode, __0, @@ -66948,7 +67115,7 @@ fn __action1398< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1399< +fn __action1401< >( source_code: &str, mode: Mode, @@ -66957,14 +67124,14 @@ fn __action1399< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1015( + __action1018( source_code, mode, __0, @@ -66974,7 +67141,7 @@ fn __action1399< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1400< +fn __action1402< >( source_code: &str, mode: Mode, @@ -66986,14 +67153,14 @@ fn __action1400< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action877( + __action878( source_code, mode, __0, @@ -67006,7 +67173,7 @@ fn __action1400< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1401< +fn __action1403< >( source_code: &str, mode: Mode, @@ -67017,14 +67184,14 @@ fn __action1401< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action878( + __action879( source_code, mode, __0, @@ -67036,7 +67203,7 @@ fn __action1401< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1402< +fn __action1404< >( source_code: &str, mode: Mode, @@ -67049,14 +67216,14 @@ fn __action1402< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action974( + __action977( source_code, mode, __0, @@ -67070,7 +67237,7 @@ fn __action1402< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1403< +fn __action1405< >( source_code: &str, mode: Mode, @@ -67082,14 +67249,14 @@ fn __action1403< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action975( + __action978( source_code, mode, __0, @@ -67102,7 +67269,7 @@ fn __action1403< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1404< +fn __action1406< >( source_code: &str, mode: Mode, @@ -67116,14 +67283,14 @@ fn __action1404< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action976( + __action979( source_code, mode, __0, @@ -67138,7 +67305,7 @@ fn __action1404< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1405< +fn __action1407< >( source_code: &str, mode: Mode, @@ -67151,14 +67318,14 @@ fn __action1405< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action977( + __action980( source_code, mode, __0, @@ -67172,7 +67339,7 @@ fn __action1405< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1406< +fn __action1408< >( source_code: &str, mode: Mode, @@ -67183,14 +67350,14 @@ fn __action1406< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action978( + __action981( source_code, mode, __0, @@ -67202,7 +67369,7 @@ fn __action1406< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1407< +fn __action1409< >( source_code: &str, mode: Mode, @@ -67212,14 +67379,14 @@ fn __action1407< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action979( + __action982( source_code, mode, __0, @@ -67230,7 +67397,7 @@ fn __action1407< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1408< +fn __action1410< >( source_code: &str, mode: Mode, @@ -67242,14 +67409,14 @@ fn __action1408< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action980( + __action983( source_code, mode, __0, @@ -67262,7 +67429,7 @@ fn __action1408< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1409< +fn __action1411< >( source_code: &str, mode: Mode, @@ -67273,14 +67440,14 @@ fn __action1409< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action981( + __action984( source_code, mode, __0, @@ -67292,7 +67459,7 @@ fn __action1409< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1410< +fn __action1412< >( source_code: &str, mode: Mode, @@ -67304,14 +67471,14 @@ fn __action1410< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action982( + __action985( source_code, mode, __0, @@ -67324,7 +67491,7 @@ fn __action1410< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1411< +fn __action1413< >( source_code: &str, mode: Mode, @@ -67335,14 +67502,14 @@ fn __action1411< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action983( + __action986( source_code, mode, __0, @@ -67354,7 +67521,7 @@ fn __action1411< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1412< +fn __action1414< >( source_code: &str, mode: Mode, @@ -67367,14 +67534,14 @@ fn __action1412< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action984( + __action987( source_code, mode, __0, @@ -67388,7 +67555,7 @@ fn __action1412< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1413< +fn __action1415< >( source_code: &str, mode: Mode, @@ -67400,14 +67567,14 @@ fn __action1413< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action985( + __action988( source_code, mode, __0, @@ -67420,7 +67587,7 @@ fn __action1413< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1414< +fn __action1416< >( source_code: &str, mode: Mode, @@ -67430,14 +67597,14 @@ fn __action1414< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action986( + __action989( source_code, mode, __0, @@ -67448,7 +67615,7 @@ fn __action1414< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1415< +fn __action1417< >( source_code: &str, mode: Mode, @@ -67457,14 +67624,14 @@ fn __action1415< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action987( + __action990( source_code, mode, __0, @@ -67474,7 +67641,7 @@ fn __action1415< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1416< +fn __action1418< >( source_code: &str, mode: Mode, @@ -67485,14 +67652,14 @@ fn __action1416< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action988( + __action991( source_code, mode, __0, @@ -67504,7 +67671,7 @@ fn __action1416< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1417< +fn __action1419< >( source_code: &str, mode: Mode, @@ -67514,14 +67681,14 @@ fn __action1417< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action989( + __action992( source_code, mode, __0, @@ -67532,7 +67699,7 @@ fn __action1417< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1418< +fn __action1420< >( source_code: &str, mode: Mode, @@ -67542,14 +67709,14 @@ fn __action1418< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action881( + __action882( source_code, mode, __0, @@ -67560,7 +67727,7 @@ fn __action1418< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1419< +fn __action1421< >( source_code: &str, mode: Mode, @@ -67569,14 +67736,14 @@ fn __action1419< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action882( + __action883( source_code, mode, __0, @@ -67586,7 +67753,7 @@ fn __action1419< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1420< +fn __action1422< >( source_code: &str, mode: Mode, @@ -67601,14 +67768,14 @@ fn __action1420< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1058( + __action1061( source_code, mode, __0, @@ -67624,7 +67791,7 @@ fn __action1420< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1421< +fn __action1423< >( source_code: &str, mode: Mode, @@ -67638,14 +67805,14 @@ fn __action1421< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1059( + __action1062( source_code, mode, __0, @@ -67660,7 +67827,7 @@ fn __action1421< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1422< +fn __action1424< >( source_code: &str, mode: Mode, @@ -67676,14 +67843,14 @@ fn __action1422< { let __start0 = __7.2; let __end0 = __7.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1060( + __action1063( source_code, mode, __0, @@ -67700,7 +67867,7 @@ fn __action1422< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1423< +fn __action1425< >( source_code: &str, mode: Mode, @@ -67715,14 +67882,14 @@ fn __action1423< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1061( + __action1064( source_code, mode, __0, @@ -67738,7 +67905,7 @@ fn __action1423< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1424< +fn __action1426< >( source_code: &str, mode: Mode, @@ -67751,14 +67918,14 @@ fn __action1424< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1062( + __action1065( source_code, mode, __0, @@ -67772,7 +67939,7 @@ fn __action1424< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1425< +fn __action1427< >( source_code: &str, mode: Mode, @@ -67784,14 +67951,14 @@ fn __action1425< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1063( + __action1066( source_code, mode, __0, @@ -67804,7 +67971,7 @@ fn __action1425< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1426< +fn __action1428< >( source_code: &str, mode: Mode, @@ -67818,14 +67985,14 @@ fn __action1426< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1064( + __action1067( source_code, mode, __0, @@ -67840,7 +68007,7 @@ fn __action1426< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1427< +fn __action1429< >( source_code: &str, mode: Mode, @@ -67853,14 +68020,14 @@ fn __action1427< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1065( + __action1068( source_code, mode, __0, @@ -67874,7 +68041,7 @@ fn __action1427< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1428< +fn __action1430< >( source_code: &str, mode: Mode, @@ -67884,14 +68051,14 @@ fn __action1428< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1066( + __action1069( source_code, mode, __0, @@ -67902,7 +68069,7 @@ fn __action1428< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1429< +fn __action1431< >( source_code: &str, mode: Mode, @@ -67916,14 +68083,14 @@ fn __action1429< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1067( + __action1070( source_code, mode, __0, @@ -67938,7 +68105,7 @@ fn __action1429< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1430< +fn __action1432< >( source_code: &str, mode: Mode, @@ -67951,14 +68118,14 @@ fn __action1430< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1068( + __action1071( source_code, mode, __0, @@ -67972,7 +68139,7 @@ fn __action1430< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1431< +fn __action1433< >( source_code: &str, mode: Mode, @@ -67987,14 +68154,14 @@ fn __action1431< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1069( + __action1072( source_code, mode, __0, @@ -68010,7 +68177,7 @@ fn __action1431< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1432< +fn __action1434< >( source_code: &str, mode: Mode, @@ -68024,14 +68191,14 @@ fn __action1432< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1070( + __action1073( source_code, mode, __0, @@ -68046,7 +68213,7 @@ fn __action1432< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1433< +fn __action1435< >( source_code: &str, mode: Mode, @@ -68058,14 +68225,14 @@ fn __action1433< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1071( + __action1074( source_code, mode, __0, @@ -68078,7 +68245,7 @@ fn __action1433< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1434< +fn __action1436< >( source_code: &str, mode: Mode, @@ -68089,14 +68256,14 @@ fn __action1434< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1072( + __action1075( source_code, mode, __0, @@ -68108,7 +68275,7 @@ fn __action1434< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1435< +fn __action1437< >( source_code: &str, mode: Mode, @@ -68121,14 +68288,14 @@ fn __action1435< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1073( + __action1076( source_code, mode, __0, @@ -68142,7 +68309,7 @@ fn __action1435< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1436< +fn __action1438< >( source_code: &str, mode: Mode, @@ -68154,14 +68321,14 @@ fn __action1436< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1074( + __action1077( source_code, mode, __0, @@ -68174,7 +68341,7 @@ fn __action1436< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1437< +fn __action1439< >( source_code: &str, mode: Mode, @@ -68183,14 +68350,14 @@ fn __action1437< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1075( + __action1078( source_code, mode, __0, @@ -68200,7 +68367,7 @@ fn __action1437< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1438< +fn __action1440< >( source_code: &str, mode: Mode, @@ -68212,14 +68379,14 @@ fn __action1438< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action885( + __action886( source_code, mode, __0, @@ -68232,7 +68399,7 @@ fn __action1438< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1439< +fn __action1441< >( source_code: &str, mode: Mode, @@ -68243,14 +68410,14 @@ fn __action1439< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action886( + __action887( source_code, mode, __0, @@ -68262,7 +68429,7 @@ fn __action1439< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1440< +fn __action1442< >( source_code: &str, mode: Mode, @@ -68275,14 +68442,14 @@ fn __action1440< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1034( + __action1037( source_code, mode, __0, @@ -68296,7 +68463,7 @@ fn __action1440< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1441< +fn __action1443< >( source_code: &str, mode: Mode, @@ -68308,14 +68475,14 @@ fn __action1441< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1035( + __action1038( source_code, mode, __0, @@ -68328,7 +68495,7 @@ fn __action1441< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1442< +fn __action1444< >( source_code: &str, mode: Mode, @@ -68342,14 +68509,14 @@ fn __action1442< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1036( + __action1039( source_code, mode, __0, @@ -68364,7 +68531,7 @@ fn __action1442< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1443< +fn __action1445< >( source_code: &str, mode: Mode, @@ -68377,14 +68544,14 @@ fn __action1443< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1037( + __action1040( source_code, mode, __0, @@ -68398,7 +68565,7 @@ fn __action1443< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1444< +fn __action1446< >( source_code: &str, mode: Mode, @@ -68409,14 +68576,14 @@ fn __action1444< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1038( + __action1041( source_code, mode, __0, @@ -68428,7 +68595,7 @@ fn __action1444< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1445< +fn __action1447< >( source_code: &str, mode: Mode, @@ -68438,14 +68605,14 @@ fn __action1445< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1039( + __action1042( source_code, mode, __0, @@ -68456,7 +68623,7 @@ fn __action1445< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1446< +fn __action1448< >( source_code: &str, mode: Mode, @@ -68468,14 +68635,14 @@ fn __action1446< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1040( + __action1043( source_code, mode, __0, @@ -68488,7 +68655,7 @@ fn __action1446< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1447< +fn __action1449< >( source_code: &str, mode: Mode, @@ -68499,14 +68666,14 @@ fn __action1447< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1041( + __action1044( source_code, mode, __0, @@ -68518,7 +68685,7 @@ fn __action1447< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1448< +fn __action1450< >( source_code: &str, mode: Mode, @@ -68530,14 +68697,14 @@ fn __action1448< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1042( + __action1045( source_code, mode, __0, @@ -68550,7 +68717,7 @@ fn __action1448< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1449< +fn __action1451< >( source_code: &str, mode: Mode, @@ -68561,14 +68728,14 @@ fn __action1449< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1043( + __action1046( source_code, mode, __0, @@ -68580,7 +68747,7 @@ fn __action1449< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1450< +fn __action1452< >( source_code: &str, mode: Mode, @@ -68593,14 +68760,14 @@ fn __action1450< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1044( + __action1047( source_code, mode, __0, @@ -68614,7 +68781,7 @@ fn __action1450< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1451< +fn __action1453< >( source_code: &str, mode: Mode, @@ -68626,14 +68793,14 @@ fn __action1451< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1045( + __action1048( source_code, mode, __0, @@ -68646,7 +68813,7 @@ fn __action1451< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1452< +fn __action1454< >( source_code: &str, mode: Mode, @@ -68656,14 +68823,14 @@ fn __action1452< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1046( + __action1049( source_code, mode, __0, @@ -68674,7 +68841,7 @@ fn __action1452< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1453< +fn __action1455< >( source_code: &str, mode: Mode, @@ -68683,14 +68850,14 @@ fn __action1453< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1047( + __action1050( source_code, mode, __0, @@ -68700,7 +68867,7 @@ fn __action1453< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1454< +fn __action1456< >( source_code: &str, mode: Mode, @@ -68711,14 +68878,14 @@ fn __action1454< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1048( + __action1051( source_code, mode, __0, @@ -68730,7 +68897,7 @@ fn __action1454< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1455< +fn __action1457< >( source_code: &str, mode: Mode, @@ -68740,14 +68907,14 @@ fn __action1455< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1049( + __action1052( source_code, mode, __0, @@ -68758,7 +68925,7 @@ fn __action1455< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1456< +fn __action1458< >( source_code: &str, mode: Mode, @@ -68768,14 +68935,14 @@ fn __action1456< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action889( + __action890( source_code, mode, __0, @@ -68786,7 +68953,7 @@ fn __action1456< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1457< +fn __action1459< >( source_code: &str, mode: Mode, @@ -68795,14 +68962,14 @@ fn __action1457< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action890( + __action891( source_code, mode, __0, @@ -68812,7 +68979,7 @@ fn __action1457< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1458< +fn __action1460< >( source_code: &str, mode: Mode, @@ -68823,14 +68990,14 @@ fn __action1458< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1223( + __action1226( source_code, mode, __0, @@ -68842,7 +69009,7 @@ fn __action1458< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1459< +fn __action1461< >( source_code: &str, mode: Mode, @@ -68852,14 +69019,14 @@ fn __action1459< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1224( + __action1227( source_code, mode, __0, @@ -68870,7 +69037,7 @@ fn __action1459< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1460< +fn __action1462< >( source_code: &str, mode: Mode, @@ -68879,14 +69046,14 @@ fn __action1460< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action904( + __action905( source_code, mode, __0, @@ -68896,7 +69063,7 @@ fn __action1460< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1461< +fn __action1463< >( source_code: &str, mode: Mode, @@ -68910,14 +69077,14 @@ fn __action1461< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action905( + __action906( source_code, mode, __0, @@ -68932,7 +69099,7 @@ fn __action1461< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1462< +fn __action1464< >( source_code: &str, mode: Mode, @@ -68945,14 +69112,14 @@ fn __action1462< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action906( + __action907( source_code, mode, __0, @@ -68966,7 +69133,7 @@ fn __action1462< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1463< +fn __action1465< >( source_code: &str, mode: Mode, @@ -68978,14 +69145,14 @@ fn __action1463< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action907( + __action908( source_code, mode, __0, @@ -68998,7 +69165,7 @@ fn __action1463< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1464< +fn __action1466< >( source_code: &str, mode: Mode, @@ -69009,14 +69176,14 @@ fn __action1464< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action908( + __action909( source_code, mode, __0, @@ -69028,7 +69195,7 @@ fn __action1464< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1465< +fn __action1467< >( source_code: &str, mode: Mode, @@ -69040,14 +69207,14 @@ fn __action1465< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action909( + __action910( source_code, mode, __0, @@ -69060,7 +69227,7 @@ fn __action1465< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1466< +fn __action1468< >( source_code: &str, mode: Mode, @@ -69071,14 +69238,14 @@ fn __action1466< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action910( + __action911( source_code, mode, __0, @@ -69090,7 +69257,7 @@ fn __action1466< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1467< +fn __action1469< >( source_code: &str, mode: Mode, @@ -69100,14 +69267,14 @@ fn __action1467< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action911( + __action912( source_code, mode, __0, @@ -69118,7 +69285,7 @@ fn __action1467< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1468< +fn __action1470< >( source_code: &str, mode: Mode, @@ -69128,14 +69295,14 @@ fn __action1468< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action912( + __action913( source_code, mode, __0, @@ -69146,7 +69313,7 @@ fn __action1468< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1469< +fn __action1471< >( source_code: &str, mode: Mode, @@ -69156,14 +69323,14 @@ fn __action1469< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action913( + __action914( source_code, mode, __0, @@ -69174,7 +69341,7 @@ fn __action1469< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1470< +fn __action1472< >( source_code: &str, mode: Mode, @@ -69183,14 +69350,14 @@ fn __action1470< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action914( + __action915( source_code, mode, __0, @@ -69200,25 +69367,25 @@ fn __action1470< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1471< +fn __action1473< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action915( + __action916( source_code, mode, __0, @@ -69230,25 +69397,25 @@ fn __action1471< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1472< +fn __action1474< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action916( + __action917( source_code, mode, __0, @@ -69260,7 +69427,7 @@ fn __action1472< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1473< +fn __action1475< >( source_code: &str, mode: Mode, @@ -69269,14 +69436,14 @@ fn __action1473< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action917( + __action918( source_code, mode, __0, @@ -69286,26 +69453,26 @@ fn __action1473< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1474< +fn __action1476< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1145( + __action1148( source_code, mode, __0, @@ -69318,24 +69485,24 @@ fn __action1474< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1475< +fn __action1477< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1146( + __action1149( source_code, mode, __0, @@ -69346,7 +69513,7 @@ fn __action1475< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1476< +fn __action1478< >( source_code: &str, mode: Mode, @@ -69357,14 +69524,14 @@ fn __action1476< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action919( + __action920( source_code, mode, __0, @@ -69376,7 +69543,7 @@ fn __action1476< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1477< +fn __action1479< >( source_code: &str, mode: Mode, @@ -69386,14 +69553,14 @@ fn __action1477< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action920( + __action921( source_code, mode, __0, @@ -69404,7 +69571,7 @@ fn __action1477< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1478< +fn __action1480< >( source_code: &str, mode: Mode, @@ -69416,14 +69583,14 @@ fn __action1478< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action921( + __action922( source_code, mode, __0, @@ -69436,7 +69603,7 @@ fn __action1478< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1479< +fn __action1481< >( source_code: &str, mode: Mode, @@ -69449,14 +69616,14 @@ fn __action1479< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action922( + __action923( source_code, mode, __0, @@ -69470,7 +69637,7 @@ fn __action1479< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1480< +fn __action1482< >( source_code: &str, mode: Mode, @@ -69482,14 +69649,14 @@ fn __action1480< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action923( + __action924( source_code, mode, __0, @@ -69502,7 +69669,7 @@ fn __action1480< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1481< +fn __action1483< >( source_code: &str, mode: Mode, @@ -69513,14 +69680,14 @@ fn __action1481< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action924( + __action925( source_code, mode, __0, @@ -69532,25 +69699,25 @@ fn __action1481< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1482< +fn __action1484< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action925( + __action926( source_code, mode, __0, @@ -69562,25 +69729,25 @@ fn __action1482< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1483< +fn __action1485< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action926( + __action927( source_code, mode, __0, @@ -69592,28 +69759,28 @@ fn __action1483< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1484< +fn __action1486< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), - __5: (TextSize, alloc::vec::Vec, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __5: (TextSize, alloc::vec::Vec, TextSize), ) -> ast::Comprehension { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action927( + __action928( source_code, mode, __0, @@ -69628,27 +69795,27 @@ fn __action1484< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1485< +fn __action1487< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), ) -> ast::Comprehension { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action928( + __action929( source_code, mode, __0, @@ -69662,24 +69829,24 @@ fn __action1485< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1486< +fn __action1488< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action930( + __action931( source_code, mode, __0, @@ -69690,7 +69857,7 @@ fn __action1486< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1487< +fn __action1489< >( source_code: &str, mode: Mode, @@ -69700,14 +69867,14 @@ fn __action1487< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action931( + __action932( source_code, mode, __0, @@ -69718,25 +69885,25 @@ fn __action1487< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1488< +fn __action1490< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Parameter { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1110( + __action1113( source_code, mode, __0, @@ -69748,7 +69915,7 @@ fn __action1488< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1489< +fn __action1491< >( source_code: &str, mode: Mode, @@ -69757,14 +69924,14 @@ fn __action1489< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1111( + __action1114( source_code, mode, __0, @@ -69774,7 +69941,7 @@ fn __action1489< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1490< +fn __action1492< >( source_code: &str, mode: Mode, @@ -69783,77 +69950,17 @@ fn __action1490< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action933( - source_code, - mode, - __0, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1491< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, core::option::Option, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option, TextSize), - __3: (TextSize, core::option::Option>, TextSize), -) -> ast::ParenthesizedExpr -{ - let __start0 = __3.2; - let __end0 = __3.2; - let __temp0 = __action413( - source_code, - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action935( - source_code, - mode, - __0, - __1, - __2, - __3, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1492< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr -{ - let __start0 = __1.2; - let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action936( + __action934( source_code, mode, __0, - __1, __temp0, ) } @@ -69864,24 +69971,22 @@ fn __action1493< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), - __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, Vec, TextSize), +) -> Result> { - let __start0 = __1.2; - let __end0 = __1.2; - let __temp0 = __action413( + let __start0 = __0.2; + let __end0 = __0.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action937( + __action936( source_code, mode, __0, - __1, __temp0, ) } @@ -69892,19 +69997,19 @@ fn __action1494< >( source_code: &str, mode: Mode, - __0: (TextSize, Vec, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, (String, StringKind, bool), TextSize), +) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action938( + __action937( source_code, mode, __0, @@ -69918,26 +70023,28 @@ fn __action1495< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, core::option::Option, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, core::option::Option, TextSize), + __3: (TextSize, core::option::Option>, TextSize), +) -> crate::parser::ParenthesizedExpr { - let __start0 = __2.2; - let __end0 = __2.2; - let __temp0 = __action413( + let __start0 = __3.2; + let __end0 = __3.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action939( + __action938( source_code, mode, __0, __1, __2, + __3, __temp0, ) } @@ -69948,26 +70055,24 @@ fn __action1496< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, token::Tok, TextSize), +) -> crate::parser::ParenthesizedExpr { - let __start0 = __2.2; - let __end0 = __2.2; - let __temp0 = __action413( + let __start0 = __1.2; + let __end0 = __1.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action940( + __action939( source_code, mode, __0, __1, - __2, __temp0, ) } @@ -69978,30 +70083,24 @@ fn __action1497< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { - let __start0 = __4.2; - let __end0 = __4.2; - let __temp0 = __action413( + let __start0 = __1.2; + let __end0 = __1.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action941( + __action940( source_code, mode, __0, __1, - __2, - __3, - __4, __temp0, ) } @@ -70012,30 +70111,22 @@ fn __action1498< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, Vec, TextSize), +) -> crate::parser::ParenthesizedExpr { - let __start0 = __4.2; - let __end0 = __4.2; - let __temp0 = __action413( + let __start0 = __0.2; + let __end0 = __0.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action942( + __action941( source_code, mode, __0, - __1, - __2, - __3, - __4, __temp0, ) } @@ -70046,24 +70137,26 @@ fn __action1499< >( source_code: &str, mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::Suite, TextSize), -) -> ast::Mod + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, ast::Operator, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { - let __start0 = __1.2; - let __end0 = __1.2; - let __temp0 = __action413( + let __start0 = __2.2; + let __end0 = __2.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action943( + __action942( source_code, mode, __0, __1, + __2, __temp0, ) } @@ -70074,24 +70167,26 @@ fn __action1500< >( source_code: &str, mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::Mod + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, ast::Operator, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { - let __start0 = __1.2; - let __end0 = __1.2; - let __temp0 = __action413( + let __start0 = __2.2; + let __end0 = __2.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1116( + __action943( source_code, mode, __0, __1, + __2, __temp0, ) } @@ -70102,26 +70197,30 @@ fn __action1501< >( source_code: &str, mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, alloc::vec::Vec, TextSize), -) -> ast::Mod + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { - let __start0 = __2.2; - let __end0 = __2.2; - let __temp0 = __action413( + let __start0 = __4.2; + let __end0 = __4.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1117( + __action944( source_code, mode, __0, __1, __2, + __3, + __4, __temp0, ) } @@ -70132,28 +70231,23 @@ fn __action1502< >( source_code: &str, mode: Mode, - __0: (TextSize, token::Tok, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::Suite, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), - __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::Suite, TextSize), - __7: (TextSize, token::Tok, TextSize), - __8: (TextSize, token::Tok, TextSize), - __9: (TextSize, ast::Suite, TextSize), -) -> ast::Stmt + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { - let __start0 = __9.2; - let __end0 = __9.2; - let __temp0 = __action413( + let __start0 = __4.2; + let __end0 = __4.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1136( + __action945( source_code, mode, __0, @@ -70161,11 +70255,6 @@ fn __action1502< __2, __3, __4, - __5, - __6, - __7, - __8, - __9, __temp0, ) } @@ -70177,33 +70266,23 @@ fn __action1503< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::Suite, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), - __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::Suite, TextSize), -) -> ast::Stmt + __1: (TextSize, ast::Suite, TextSize), +) -> ast::Mod { - let __start0 = __6.2; - let __end0 = __6.2; - let __temp0 = __action413( + let __start0 = __1.2; + let __end0 = __1.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1137( + __action946( source_code, mode, __0, __1, - __2, - __3, - __4, - __5, - __6, __temp0, ) } @@ -70215,33 +70294,23 @@ fn __action1504< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::Suite, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), - __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::Suite, TextSize), -) -> ast::Stmt + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> ast::Mod { - let __start0 = __6.2; - let __end0 = __6.2; - let __temp0 = __action413( + let __start0 = __1.2; + let __end0 = __1.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1138( + __action1119( source_code, mode, __0, __1, - __2, - __3, - __4, - __5, - __6, __temp0, ) } @@ -70253,27 +70322,25 @@ fn __action1505< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::Suite, TextSize), - __3: (TextSize, alloc::vec::Vec, TextSize), -) -> ast::Stmt + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, alloc::vec::Vec, TextSize), +) -> ast::Mod { - let __start0 = __3.2; - let __end0 = __3.2; - let __temp0 = __action413( + let __start0 = __2.2; + let __end0 = __2.2; + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1139( + __action1120( source_code, mode, __0, __1, __2, - __3, __temp0, ) } @@ -70298,14 +70365,14 @@ fn __action1506< { let __start0 = __9.2; let __end0 = __9.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1140( + __action1139( source_code, mode, __0, @@ -70339,14 +70406,14 @@ fn __action1507< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1141( + __action1140( source_code, mode, __0, @@ -70377,14 +70444,14 @@ fn __action1508< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1142( + __action1141( source_code, mode, __0, @@ -70412,14 +70479,14 @@ fn __action1509< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1143( + __action1142( source_code, mode, __0, @@ -70433,6 +70500,158 @@ fn __action1509< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] fn __action1510< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::Suite, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), + __4: (TextSize, token::Tok, TextSize), + __5: (TextSize, token::Tok, TextSize), + __6: (TextSize, ast::Suite, TextSize), + __7: (TextSize, token::Tok, TextSize), + __8: (TextSize, token::Tok, TextSize), + __9: (TextSize, ast::Suite, TextSize), +) -> ast::Stmt +{ + let __start0 = __9.2; + let __end0 = __9.2; + let __temp0 = __action416( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1143( + source_code, + mode, + __0, + __1, + __2, + __3, + __4, + __5, + __6, + __7, + __8, + __9, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1511< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::Suite, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), + __4: (TextSize, token::Tok, TextSize), + __5: (TextSize, token::Tok, TextSize), + __6: (TextSize, ast::Suite, TextSize), +) -> ast::Stmt +{ + let __start0 = __6.2; + let __end0 = __6.2; + let __temp0 = __action416( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1144( + source_code, + mode, + __0, + __1, + __2, + __3, + __4, + __5, + __6, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1512< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::Suite, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), + __4: (TextSize, token::Tok, TextSize), + __5: (TextSize, token::Tok, TextSize), + __6: (TextSize, ast::Suite, TextSize), +) -> ast::Stmt +{ + let __start0 = __6.2; + let __end0 = __6.2; + let __temp0 = __action416( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1145( + source_code, + mode, + __0, + __1, + __2, + __3, + __4, + __5, + __6, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1513< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::Suite, TextSize), + __3: (TextSize, alloc::vec::Vec, TextSize), +) -> ast::Stmt +{ + let __start0 = __3.2; + let __end0 = __3.2; + let __temp0 = __action416( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1146( + source_code, + mode, + __0, + __1, + __2, + __3, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1514< >( source_code: &str, mode: Mode, @@ -70441,14 +70660,14 @@ fn __action1510< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action948( + __action951( source_code, mode, __0, @@ -70458,7 +70677,7 @@ fn __action1510< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1511< +fn __action1515< >( source_code: &str, mode: Mode, @@ -70466,19 +70685,19 @@ fn __action1511< __1: (TextSize, ast::Expr, TextSize), __2: (TextSize, core::option::Option, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action949( + __action952( source_code, mode, __0, @@ -70492,25 +70711,25 @@ fn __action1511< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1512< +fn __action1516< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::TypeParam { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1105( + __action1108( source_code, mode, __0, @@ -70522,7 +70741,7 @@ fn __action1512< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1513< +fn __action1517< >( source_code: &str, mode: Mode, @@ -70531,14 +70750,14 @@ fn __action1513< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1106( + __action1109( source_code, mode, __0, @@ -70548,7 +70767,7 @@ fn __action1513< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1514< +fn __action1518< >( source_code: &str, mode: Mode, @@ -70558,14 +70777,14 @@ fn __action1514< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action951( + __action954( source_code, mode, __0, @@ -70576,7 +70795,7 @@ fn __action1514< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1515< +fn __action1519< >( source_code: &str, mode: Mode, @@ -70586,14 +70805,14 @@ fn __action1515< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action952( + __action955( source_code, mode, __0, @@ -70604,7 +70823,7 @@ fn __action1515< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1516< +fn __action1520< >( source_code: &str, mode: Mode, @@ -70616,14 +70835,14 @@ fn __action1516< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action953( + __action956( source_code, mode, __0, @@ -70636,7 +70855,7 @@ fn __action1516< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1517< +fn __action1521< >( source_code: &str, mode: Mode, @@ -70647,14 +70866,14 @@ fn __action1517< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action954( + __action957( source_code, mode, __0, @@ -70666,25 +70885,25 @@ fn __action1517< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1518< +fn __action1522< >( source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::ParameterWithDefault { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1107( + __action1110( source_code, mode, __0, @@ -70696,7 +70915,7 @@ fn __action1518< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1519< +fn __action1523< >( source_code: &str, mode: Mode, @@ -70705,14 +70924,14 @@ fn __action1519< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1108( + __action1111( source_code, mode, __0, @@ -70722,7 +70941,7 @@ fn __action1519< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1520< +fn __action1524< >( source_code: &str, mode: Mode, @@ -70731,14 +70950,14 @@ fn __action1520< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action956( + __action959( source_code, mode, __0, @@ -70748,7 +70967,7 @@ fn __action1520< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1521< +fn __action1525< >( source_code: &str, mode: Mode, @@ -70757,14 +70976,14 @@ fn __action1521< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action957( + __action960( source_code, mode, __0, @@ -70774,25 +70993,25 @@ fn __action1521< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1522< +fn __action1526< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::WithItem { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action959( + __action962( source_code, mode, __0, @@ -70804,25 +71023,25 @@ fn __action1522< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1523< +fn __action1527< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action962( + __action965( source_code, mode, __0, @@ -70834,25 +71053,25 @@ fn __action1523< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1524< +fn __action1528< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action963( + __action966( source_code, mode, __0, @@ -70864,24 +71083,24 @@ fn __action1524< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1525< +fn __action1529< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, core::option::Option, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action964( + __action967( source_code, mode, __0, @@ -70892,25 +71111,25 @@ fn __action1525< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1526< +fn __action1530< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action413( + let __temp0 = __action416( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action965( + __action968( source_code, mode, __0, @@ -70922,7 +71141,7 @@ fn __action1526< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1527< +fn __action1531< >( source_code: &str, mode: Mode, @@ -70937,13 +71156,13 @@ fn __action1527< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action286( + let __temp0 = __action291( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action781( + __action782( source_code, mode, __0, @@ -70958,7 +71177,7 @@ fn __action1527< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1528< +fn __action1532< >( source_code: &str, mode: Mode, @@ -70972,14 +71191,14 @@ fn __action1528< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action287( + let __temp0 = __action292( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action781( + __action782( source_code, mode, __0, @@ -70994,23 +71213,23 @@ fn __action1528< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1529< +fn __action1533< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action403( + let __temp0 = __action406( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1309( + __action1310( source_code, mode, __0, @@ -71020,23 +71239,23 @@ fn __action1529< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1530< +fn __action1534< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), ) -> Result> { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action404( + let __temp0 = __action407( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1309( + __action1310( source_code, mode, __0, @@ -71046,25 +71265,25 @@ fn __action1530< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1531< +fn __action1535< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action398( + let __temp0 = __action401( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1311( + __action1312( source_code, mode, __0, @@ -71076,25 +71295,25 @@ fn __action1531< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1532< +fn __action1536< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action399( + let __temp0 = __action402( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1311( + __action1312( source_code, mode, __0, @@ -71106,7 +71325,7 @@ fn __action1532< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1533< +fn __action1537< >( source_code: &str, mode: Mode, @@ -71115,13 +71334,13 @@ fn __action1533< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action464( + let __temp0 = __action467( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1160( + __action1163( source_code, mode, __temp0, @@ -71130,7 +71349,7 @@ fn __action1533< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1534< +fn __action1538< >( source_code: &str, mode: Mode, @@ -71140,14 +71359,14 @@ fn __action1534< { let __start0 = *__lookbehind; let __end0 = *__lookahead; - let __temp0 = __action465( + let __temp0 = __action468( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1160( + __action1163( source_code, mode, __temp0, @@ -71156,7 +71375,7 @@ fn __action1534< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1535< +fn __action1539< >( source_code: &str, mode: Mode, @@ -71166,13 +71385,13 @@ fn __action1535< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action464( + let __temp0 = __action467( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1161( + __action1164( source_code, mode, __0, @@ -71182,7 +71401,7 @@ fn __action1535< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1536< +fn __action1540< >( source_code: &str, mode: Mode, @@ -71191,14 +71410,14 @@ fn __action1536< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action465( + let __temp0 = __action468( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1161( + __action1164( source_code, mode, __0, @@ -71208,7 +71427,7 @@ fn __action1536< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1537< +fn __action1541< >( source_code: &str, mode: Mode, @@ -71219,13 +71438,13 @@ fn __action1537< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1533( + let __temp0 = __action1537( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1230( + __action1233( source_code, mode, __0, @@ -71236,7 +71455,7 @@ fn __action1537< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1538< +fn __action1542< >( source_code: &str, mode: Mode, @@ -71246,14 +71465,14 @@ fn __action1538< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action1534( + let __temp0 = __action1538( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1230( + __action1233( source_code, mode, __0, @@ -71264,7 +71483,7 @@ fn __action1538< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1539< +fn __action1543< >( source_code: &str, mode: Mode, @@ -71276,14 +71495,14 @@ fn __action1539< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1535( + let __temp0 = __action1539( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1230( + __action1233( source_code, mode, __0, @@ -71294,7 +71513,7 @@ fn __action1539< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1540< +fn __action1544< >( source_code: &str, mode: Mode, @@ -71305,13 +71524,13 @@ fn __action1540< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1536( + let __temp0 = __action1540( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1230( + __action1233( source_code, mode, __0, @@ -71322,7 +71541,7 @@ fn __action1540< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1541< +fn __action1545< >( source_code: &str, mode: Mode, @@ -71331,13 +71550,13 @@ fn __action1541< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action426( + let __temp0 = __action429( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1183( + __action1186( source_code, mode, __temp0, @@ -71346,7 +71565,7 @@ fn __action1541< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1542< +fn __action1546< >( source_code: &str, mode: Mode, @@ -71356,14 +71575,14 @@ fn __action1542< { let __start0 = *__lookbehind; let __end0 = *__lookahead; - let __temp0 = __action427( + let __temp0 = __action430( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1183( + __action1186( source_code, mode, __temp0, @@ -71372,7 +71591,7 @@ fn __action1542< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1543< +fn __action1547< >( source_code: &str, mode: Mode, @@ -71382,13 +71601,13 @@ fn __action1543< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action426( + let __temp0 = __action429( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1184( + __action1187( source_code, mode, __0, @@ -71398,7 +71617,7 @@ fn __action1543< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1544< +fn __action1548< >( source_code: &str, mode: Mode, @@ -71407,14 +71626,14 @@ fn __action1544< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action427( + let __temp0 = __action430( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1184( + __action1187( source_code, mode, __0, @@ -71424,7 +71643,7 @@ fn __action1544< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1545< +fn __action1549< >( source_code: &str, mode: Mode, @@ -71435,13 +71654,13 @@ fn __action1545< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1541( + let __temp0 = __action1545( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1481( + __action1483( source_code, mode, __0, @@ -71452,7 +71671,7 @@ fn __action1545< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1546< +fn __action1550< >( source_code: &str, mode: Mode, @@ -71462,14 +71681,14 @@ fn __action1546< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action1542( + let __temp0 = __action1546( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1481( + __action1483( source_code, mode, __0, @@ -71480,7 +71699,7 @@ fn __action1546< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1547< +fn __action1551< >( source_code: &str, mode: Mode, @@ -71492,14 +71711,14 @@ fn __action1547< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1543( + let __temp0 = __action1547( source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1481( + __action1483( source_code, mode, __0, @@ -71510,7 +71729,7 @@ fn __action1547< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1548< +fn __action1552< >( source_code: &str, mode: Mode, @@ -71521,13 +71740,13 @@ fn __action1548< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1544( + let __temp0 = __action1548( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1481( + __action1483( source_code, mode, __0, @@ -71538,23 +71757,23 @@ fn __action1548< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1549< +fn __action1553< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, Vec, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action247( + let __temp0 = __action250( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1322( + __action1324( source_code, mode, __0, @@ -71564,23 +71783,23 @@ fn __action1549< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1550< +fn __action1554< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action248( + let __temp0 = __action251( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1322( + __action1324( source_code, mode, __0, @@ -71590,27 +71809,27 @@ fn __action1550< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1551< +fn __action1555< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Comprehension { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action250( + let __temp0 = __action253( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1484( + __action1486( source_code, mode, __0, @@ -71624,27 +71843,27 @@ fn __action1551< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1552< +fn __action1556< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), - __5: (TextSize, alloc::vec::Vec, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __5: (TextSize, alloc::vec::Vec, TextSize), ) -> ast::Comprehension { let __start0 = __5.0; let __end0 = __5.2; - let __temp0 = __action251( + let __temp0 = __action254( source_code, mode, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action1484( + __action1486( source_code, mode, __0, @@ -71658,26 +71877,26 @@ fn __action1552< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1553< +fn __action1557< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Comprehension { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action250( + let __temp0 = __action253( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1485( + __action1487( source_code, mode, __0, @@ -71690,26 +71909,26 @@ fn __action1553< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1554< +fn __action1558< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), - __4: (TextSize, alloc::vec::Vec, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __4: (TextSize, alloc::vec::Vec, TextSize), ) -> ast::Comprehension { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action251( + let __temp0 = __action254( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1485( + __action1487( source_code, mode, __0, @@ -71722,7 +71941,7 @@ fn __action1554< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1555< +fn __action1559< >( source_code: &str, mode: Mode, @@ -71736,14 +71955,14 @@ fn __action1555< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action306( + let __temp0 = __action311( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1527( + __action1531( source_code, mode, __temp0, @@ -71758,7 +71977,7 @@ fn __action1555< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1556< +fn __action1560< >( source_code: &str, mode: Mode, @@ -71773,13 +71992,13 @@ fn __action1556< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action307( + let __temp0 = __action312( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1527( + __action1531( source_code, mode, __temp0, @@ -71794,7 +72013,7 @@ fn __action1556< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1557< +fn __action1561< >( source_code: &str, mode: Mode, @@ -71807,14 +72026,14 @@ fn __action1557< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action306( + let __temp0 = __action311( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1528( + __action1532( source_code, mode, __temp0, @@ -71828,7 +72047,7 @@ fn __action1557< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1558< +fn __action1562< >( source_code: &str, mode: Mode, @@ -71842,13 +72061,13 @@ fn __action1558< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action307( + let __temp0 = __action312( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1528( + __action1532( source_code, mode, __temp0, @@ -71862,7 +72081,7 @@ fn __action1558< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1559< +fn __action1563< >( source_code: &str, mode: Mode, @@ -71872,21 +72091,21 @@ fn __action1559< __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, ast::Parameters, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::ParenthesizedExpr, TextSize), + __6: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __7: (TextSize, token::Tok, TextSize), __8: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action306( + let __temp0 = __action311( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1096( + __action1099( source_code, mode, __temp0, @@ -71904,7 +72123,7 @@ fn __action1559< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1560< +fn __action1564< >( source_code: &str, mode: Mode, @@ -71915,20 +72134,20 @@ fn __action1560< __4: (TextSize, core::option::Option, TextSize), __5: (TextSize, ast::Parameters, TextSize), __6: (TextSize, token::Tok, TextSize), - __7: (TextSize, ast::ParenthesizedExpr, TextSize), + __7: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __8: (TextSize, token::Tok, TextSize), __9: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action307( + let __temp0 = __action312( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1096( + __action1099( source_code, mode, __temp0, @@ -71946,7 +72165,7 @@ fn __action1560< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1561< +fn __action1565< >( source_code: &str, mode: Mode, @@ -71961,14 +72180,14 @@ fn __action1561< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action306( + let __temp0 = __action311( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1097( + __action1100( source_code, mode, __temp0, @@ -71984,7 +72203,7 @@ fn __action1561< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1562< +fn __action1566< >( source_code: &str, mode: Mode, @@ -72000,13 +72219,13 @@ fn __action1562< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action307( + let __temp0 = __action312( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1097( + __action1100( source_code, mode, __temp0, @@ -72022,7 +72241,7 @@ fn __action1562< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1563< +fn __action1567< >( source_code: &str, mode: Mode, @@ -72031,21 +72250,21 @@ fn __action1563< __2: (TextSize, core::option::Option, TextSize), __3: (TextSize, ast::Parameters, TextSize), __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, ast::ParenthesizedExpr, TextSize), + __5: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action306( + let __temp0 = __action311( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1098( + __action1101( source_code, mode, __temp0, @@ -72062,7 +72281,7 @@ fn __action1563< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1564< +fn __action1568< >( source_code: &str, mode: Mode, @@ -72072,20 +72291,20 @@ fn __action1564< __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, ast::Parameters, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::ParenthesizedExpr, TextSize), + __6: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __7: (TextSize, token::Tok, TextSize), __8: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action307( + let __temp0 = __action312( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1098( + __action1101( source_code, mode, __temp0, @@ -72102,7 +72321,7 @@ fn __action1564< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1565< +fn __action1569< >( source_code: &str, mode: Mode, @@ -72116,14 +72335,14 @@ fn __action1565< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action306( + let __temp0 = __action311( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1099( + __action1102( source_code, mode, __temp0, @@ -72138,7 +72357,7 @@ fn __action1565< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1566< +fn __action1570< >( source_code: &str, mode: Mode, @@ -72153,13 +72372,13 @@ fn __action1566< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action307( + let __temp0 = __action312( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1099( + __action1102( source_code, mode, __temp0, @@ -72174,24 +72393,24 @@ fn __action1566< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1567< +fn __action1571< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), + __1: (TextSize, Vec<(Option>, crate::parser::ParenthesizedExpr)>, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action564( + let __temp0 = __action567( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1255( + __action1257( source_code, mode, __0, @@ -72202,24 +72421,24 @@ fn __action1567< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1568< +fn __action1572< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action565( + let __temp0 = __action568( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1255( + __action1257( source_code, mode, __0, @@ -72230,24 +72449,24 @@ fn __action1568< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1569< +fn __action1573< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), + __1: (TextSize, Vec<(Option>, crate::parser::ParenthesizedExpr)>, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action564( + let __temp0 = __action567( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1280( + __action1281( source_code, mode, __0, @@ -72258,24 +72477,24 @@ fn __action1569< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1570< +fn __action1574< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action565( + let __temp0 = __action568( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1280( + __action1281( source_code, mode, __0, @@ -72286,7 +72505,7 @@ fn __action1570< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1571< +fn __action1575< >( source_code: &str, mode: Mode, @@ -72296,13 +72515,13 @@ fn __action1571< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action498( + let __temp0 = __action501( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action438( + __action441( source_code, mode, __0, @@ -72312,7 +72531,7 @@ fn __action1571< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1572< +fn __action1576< >( source_code: &str, mode: Mode, @@ -72321,14 +72540,14 @@ fn __action1572< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action499( + let __temp0 = __action502( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action438( + __action441( source_code, mode, __0, @@ -72338,27 +72557,27 @@ fn __action1572< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1573< +fn __action1577< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, (TextSize, ast::ConversionFlag), TextSize), - __4: (TextSize, core::option::Option, TextSize), + __4: (TextSize, core::option::Option, TextSize), __5: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action266( + let __temp0 = __action269( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1314( + __action1316( source_code, mode, __0, @@ -72372,27 +72591,27 @@ fn __action1573< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1574< +fn __action1578< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, core::option::Option, TextSize), + __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action267( + let __temp0 = __action270( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1314( + __action1316( source_code, mode, __0, @@ -72406,26 +72625,26 @@ fn __action1574< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1575< +fn __action1579< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, (TextSize, ast::ConversionFlag), TextSize), - __3: (TextSize, core::option::Option, TextSize), + __3: (TextSize, core::option::Option, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action266( + let __temp0 = __action269( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1315( + __action1317( source_code, mode, __0, @@ -72438,26 +72657,26 @@ fn __action1575< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1576< +fn __action1580< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, core::option::Option, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, core::option::Option, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action267( + let __temp0 = __action270( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1315( + __action1317( source_code, mode, __0, @@ -72470,27 +72689,27 @@ fn __action1576< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1577< +fn __action1581< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, (TextSize, ast::ConversionFlag), TextSize), - __4: (TextSize, ast::Expr, TextSize), + __4: (TextSize, ast::FStringFormatSpec, TextSize), __5: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action264( + let __temp0 = __action267( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1573( + __action1577( source_code, mode, __0, @@ -72504,27 +72723,27 @@ fn __action1577< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1578< +fn __action1582< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, (TextSize, ast::ConversionFlag), TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action265( + let __temp0 = __action268( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1573( + __action1577( source_code, mode, __0, @@ -72538,26 +72757,26 @@ fn __action1578< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1579< +fn __action1583< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::Expr, TextSize), + __3: (TextSize, ast::FStringFormatSpec, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action264( + let __temp0 = __action267( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1574( + __action1578( source_code, mode, __0, @@ -72570,26 +72789,26 @@ fn __action1579< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1580< +fn __action1584< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action265( + let __temp0 = __action268( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1574( + __action1578( source_code, mode, __0, @@ -72602,26 +72821,26 @@ fn __action1580< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1581< +fn __action1585< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, (TextSize, ast::ConversionFlag), TextSize), - __3: (TextSize, ast::Expr, TextSize), + __3: (TextSize, ast::FStringFormatSpec, TextSize), __4: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action264( + let __temp0 = __action267( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1575( + __action1579( source_code, mode, __0, @@ -72634,26 +72853,26 @@ fn __action1581< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1582< +fn __action1586< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, (TextSize, ast::ConversionFlag), TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action265( + let __temp0 = __action268( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1575( + __action1579( source_code, mode, __0, @@ -72666,25 +72885,25 @@ fn __action1582< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1583< +fn __action1587< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, ast::Expr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, ast::FStringFormatSpec, TextSize), __3: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action264( + let __temp0 = __action267( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1576( + __action1580( source_code, mode, __0, @@ -72696,25 +72915,25 @@ fn __action1583< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1584< +fn __action1588< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> Result> +) -> Result> { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action265( + let __temp0 = __action268( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1576( + __action1580( source_code, mode, __0, @@ -72726,7 +72945,7 @@ fn __action1584< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1585< +fn __action1589< >( source_code: &str, mode: Mode, @@ -72736,14 +72955,14 @@ fn __action1585< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action270( + let __temp0 = __action273( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1312( + __action1313( source_code, mode, __0, @@ -72754,24 +72973,24 @@ fn __action1585< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1586< +fn __action1590< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), __2: (TextSize, token::Tok, TextSize), ) -> StringType { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action271( + let __temp0 = __action274( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1312( + __action1313( source_code, mode, __0, @@ -72782,76 +73001,24 @@ fn __action1586< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1587< +fn __action1591< >( source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> ast::Expr +) -> ast::FStringFormatSpec { let __start0 = *__lookbehind; let __end0 = *__lookahead; - let __temp0 = __action270( + let __temp0 = __action273( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1313( - source_code, - mode, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1588< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, alloc::vec::Vec, TextSize), -) -> ast::Expr -{ - let __start0 = __0.0; - let __end0 = __0.2; - let __temp0 = __action271( - source_code, - mode, - __0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action1313( - source_code, - mode, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1589< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, ast::Identifier, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::Identifier, TextSize), -) -> Vec -{ - let __start0 = __0.0; - let __end0 = __2.2; - let __temp0 = __action1332( - source_code, - mode, - __0, - __1, - __2, - ); - let __temp0 = (__start0, __temp0, __end0); - __action390( + __action1314( source_code, mode, __temp0, @@ -72860,84 +73027,24 @@ fn __action1589< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1590< +fn __action1592< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::Identifier, TextSize), -) -> Vec + __0: (TextSize, alloc::vec::Vec, TextSize), +) -> ast::FStringFormatSpec { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1333( - source_code, - mode, - __0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action390( - source_code, - mode, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1591< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, Vec, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::Identifier, TextSize), - __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::Identifier, TextSize), -) -> Vec -{ - let __start0 = __2.0; - let __end0 = __4.2; - let __temp0 = __action1332( - source_code, - mode, - __2, - __3, - __4, - ); - let __temp0 = (__start0, __temp0, __end0); - __action391( + let __temp0 = __action274( source_code, mode, __0, - __1, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1592< ->( - source_code: &str, - mode: Mode, - __0: (TextSize, Vec, TextSize), - __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::Identifier, TextSize), -) -> Vec -{ - let __start0 = __2.0; - let __end0 = __2.2; - let __temp0 = __action1333( - source_code, - mode, - __2, ); let __temp0 = (__start0, __temp0, __end0); - __action391( + __action1314( source_code, mode, - __0, - __1, __temp0, ) } @@ -72963,7 +73070,7 @@ fn __action1593< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action383( + __action393( source_code, mode, __temp0, @@ -72987,7 +73094,7 @@ fn __action1594< __0, ); let __temp0 = (__start0, __temp0, __end0); - __action383( + __action393( source_code, mode, __temp0, @@ -73017,7 +73124,7 @@ fn __action1595< __4, ); let __temp0 = (__start0, __temp0, __end0); - __action384( + __action394( source_code, mode, __0, @@ -73045,7 +73152,7 @@ fn __action1596< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action384( + __action394( source_code, mode, __0, @@ -73057,6 +73164,118 @@ fn __action1596< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] fn __action1597< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, ast::Identifier, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::Identifier, TextSize), +) -> Vec +{ + let __start0 = __0.0; + let __end0 = __2.2; + let __temp0 = __action1336( + source_code, + mode, + __0, + __1, + __2, + ); + let __temp0 = (__start0, __temp0, __end0); + __action386( + source_code, + mode, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1598< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, ast::Identifier, TextSize), +) -> Vec +{ + let __start0 = __0.0; + let __end0 = __0.2; + let __temp0 = __action1337( + source_code, + mode, + __0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action386( + source_code, + mode, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1599< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, Vec, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::Identifier, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, ast::Identifier, TextSize), +) -> Vec +{ + let __start0 = __2.0; + let __end0 = __4.2; + let __temp0 = __action1336( + source_code, + mode, + __2, + __3, + __4, + ); + let __temp0 = (__start0, __temp0, __end0); + __action387( + source_code, + mode, + __0, + __1, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1600< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, Vec, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::Identifier, TextSize), +) -> Vec +{ + let __start0 = __2.0; + let __end0 = __2.2; + let __temp0 = __action1337( + source_code, + mode, + __2, + ); + let __temp0 = (__start0, __temp0, __end0); + __action387( + source_code, + mode, + __0, + __1, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1601< >( source_code: &str, mode: Mode, @@ -73065,7 +73284,7 @@ fn __action1597< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action388( + let __temp0 = __action391( source_code, mode, &__start0, @@ -73082,7 +73301,7 @@ fn __action1597< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1598< +fn __action1602< >( source_code: &str, mode: Mode, @@ -73092,7 +73311,7 @@ fn __action1598< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action389( + let __temp0 = __action392( source_code, mode, __0, @@ -73108,24 +73327,24 @@ fn __action1598< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1599< +fn __action1603< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action572( + let __temp0 = __action575( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1239( + __action1241( source_code, mode, __0, @@ -73136,24 +73355,24 @@ fn __action1599< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1600< +fn __action1604< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action573( + let __temp0 = __action576( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1239( + __action1241( source_code, mode, __0, @@ -73164,24 +73383,24 @@ fn __action1600< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1601< +fn __action1605< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Vec, TextSize), + __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action572( + let __temp0 = __action575( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1266( + __action1267( source_code, mode, __0, @@ -73192,24 +73411,24 @@ fn __action1601< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1602< +fn __action1606< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action573( + let __temp0 = __action576( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1266( + __action1267( source_code, mode, __0, @@ -73220,7 +73439,7 @@ fn __action1602< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1603< +fn __action1607< >( source_code: &str, mode: Mode, @@ -73235,13 +73454,13 @@ fn __action1603< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1382( + __action1384( source_code, mode, __temp0, @@ -73256,7 +73475,7 @@ fn __action1603< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1604< +fn __action1608< >( source_code: &str, mode: Mode, @@ -73273,7 +73492,7 @@ fn __action1604< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -73281,7 +73500,7 @@ fn __action1604< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1382( + __action1384( source_code, mode, __temp0, @@ -73296,7 +73515,7 @@ fn __action1604< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1605< +fn __action1609< >( source_code: &str, mode: Mode, @@ -73314,7 +73533,7 @@ fn __action1605< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -73323,7 +73542,7 @@ fn __action1605< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1382( + __action1384( source_code, mode, __temp0, @@ -73338,7 +73557,7 @@ fn __action1605< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1606< +fn __action1610< >( source_code: &str, mode: Mode, @@ -73352,13 +73571,13 @@ fn __action1606< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1383( + __action1385( source_code, mode, __temp0, @@ -73372,7 +73591,7 @@ fn __action1606< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1607< +fn __action1611< >( source_code: &str, mode: Mode, @@ -73388,7 +73607,7 @@ fn __action1607< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -73396,7 +73615,7 @@ fn __action1607< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1383( + __action1385( source_code, mode, __temp0, @@ -73410,7 +73629,7 @@ fn __action1607< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1608< +fn __action1612< >( source_code: &str, mode: Mode, @@ -73427,7 +73646,7 @@ fn __action1608< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -73436,7 +73655,7 @@ fn __action1608< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1383( + __action1385( source_code, mode, __temp0, @@ -73450,7 +73669,7 @@ fn __action1608< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1609< +fn __action1613< >( source_code: &str, mode: Mode, @@ -73466,13 +73685,13 @@ fn __action1609< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1384( + __action1386( source_code, mode, __temp0, @@ -73488,7 +73707,7 @@ fn __action1609< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1610< +fn __action1614< >( source_code: &str, mode: Mode, @@ -73506,7 +73725,7 @@ fn __action1610< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -73514,7 +73733,7 @@ fn __action1610< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1384( + __action1386( source_code, mode, __temp0, @@ -73530,7 +73749,7 @@ fn __action1610< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1611< +fn __action1615< >( source_code: &str, mode: Mode, @@ -73549,7 +73768,7 @@ fn __action1611< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -73558,7 +73777,7 @@ fn __action1611< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1384( + __action1386( source_code, mode, __temp0, @@ -73574,7 +73793,7 @@ fn __action1611< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1612< +fn __action1616< >( source_code: &str, mode: Mode, @@ -73589,13 +73808,13 @@ fn __action1612< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1385( + __action1387( source_code, mode, __temp0, @@ -73610,7 +73829,7 @@ fn __action1612< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1613< +fn __action1617< >( source_code: &str, mode: Mode, @@ -73627,7 +73846,7 @@ fn __action1613< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -73635,7 +73854,7 @@ fn __action1613< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1385( + __action1387( source_code, mode, __temp0, @@ -73650,7 +73869,7 @@ fn __action1613< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1614< +fn __action1618< >( source_code: &str, mode: Mode, @@ -73668,7 +73887,7 @@ fn __action1614< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -73677,7 +73896,7 @@ fn __action1614< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1385( + __action1387( source_code, mode, __temp0, @@ -73692,7 +73911,7 @@ fn __action1614< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1615< +fn __action1619< >( source_code: &str, mode: Mode, @@ -73705,13 +73924,13 @@ fn __action1615< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1386( + __action1388( source_code, mode, __temp0, @@ -73724,7 +73943,7 @@ fn __action1615< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1616< +fn __action1620< >( source_code: &str, mode: Mode, @@ -73739,7 +73958,7 @@ fn __action1616< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -73747,7 +73966,7 @@ fn __action1616< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1386( + __action1388( source_code, mode, __temp0, @@ -73760,7 +73979,7 @@ fn __action1616< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1617< +fn __action1621< >( source_code: &str, mode: Mode, @@ -73776,7 +73995,7 @@ fn __action1617< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -73785,7 +74004,7 @@ fn __action1617< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1386( + __action1388( source_code, mode, __temp0, @@ -73798,7 +74017,7 @@ fn __action1617< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1618< +fn __action1622< >( source_code: &str, mode: Mode, @@ -73810,13 +74029,13 @@ fn __action1618< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1387( + __action1389( source_code, mode, __temp0, @@ -73828,7 +74047,7 @@ fn __action1618< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1619< +fn __action1623< >( source_code: &str, mode: Mode, @@ -73842,7 +74061,7 @@ fn __action1619< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -73850,7 +74069,7 @@ fn __action1619< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1387( + __action1389( source_code, mode, __temp0, @@ -73862,7 +74081,7 @@ fn __action1619< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1620< +fn __action1624< >( source_code: &str, mode: Mode, @@ -73877,7 +74096,7 @@ fn __action1620< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -73886,7 +74105,7 @@ fn __action1620< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1387( + __action1389( source_code, mode, __temp0, @@ -73898,7 +74117,7 @@ fn __action1620< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1621< +fn __action1625< >( source_code: &str, mode: Mode, @@ -73912,13 +74131,13 @@ fn __action1621< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1388( + __action1390( source_code, mode, __temp0, @@ -73932,7 +74151,7 @@ fn __action1621< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1622< +fn __action1626< >( source_code: &str, mode: Mode, @@ -73948,7 +74167,7 @@ fn __action1622< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -73956,7 +74175,7 @@ fn __action1622< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1388( + __action1390( source_code, mode, __temp0, @@ -73970,7 +74189,7 @@ fn __action1622< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1623< +fn __action1627< >( source_code: &str, mode: Mode, @@ -73987,7 +74206,7 @@ fn __action1623< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -73996,7 +74215,7 @@ fn __action1623< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1388( + __action1390( source_code, mode, __temp0, @@ -74010,7 +74229,7 @@ fn __action1623< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1624< +fn __action1628< >( source_code: &str, mode: Mode, @@ -74023,13 +74242,13 @@ fn __action1624< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1389( + __action1391( source_code, mode, __temp0, @@ -74042,7 +74261,7 @@ fn __action1624< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1625< +fn __action1629< >( source_code: &str, mode: Mode, @@ -74057,7 +74276,7 @@ fn __action1625< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74065,7 +74284,7 @@ fn __action1625< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1389( + __action1391( source_code, mode, __temp0, @@ -74078,7 +74297,7 @@ fn __action1625< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1626< +fn __action1630< >( source_code: &str, mode: Mode, @@ -74094,7 +74313,7 @@ fn __action1626< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74103,7 +74322,7 @@ fn __action1626< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1389( + __action1391( source_code, mode, __temp0, @@ -74116,7 +74335,7 @@ fn __action1626< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1627< +fn __action1631< >( source_code: &str, mode: Mode, @@ -74126,13 +74345,13 @@ fn __action1627< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1390( + __action1392( source_code, mode, __temp0, @@ -74142,7 +74361,7 @@ fn __action1627< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1628< +fn __action1632< >( source_code: &str, mode: Mode, @@ -74154,7 +74373,7 @@ fn __action1628< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74162,7 +74381,7 @@ fn __action1628< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1390( + __action1392( source_code, mode, __temp0, @@ -74172,7 +74391,7 @@ fn __action1628< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1629< +fn __action1633< >( source_code: &str, mode: Mode, @@ -74185,7 +74404,7 @@ fn __action1629< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74194,7 +74413,7 @@ fn __action1629< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1390( + __action1392( source_code, mode, __temp0, @@ -74204,7 +74423,7 @@ fn __action1629< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1630< +fn __action1634< >( source_code: &str, mode: Mode, @@ -74218,13 +74437,13 @@ fn __action1630< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1391( + __action1393( source_code, mode, __temp0, @@ -74238,7 +74457,7 @@ fn __action1630< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1631< +fn __action1635< >( source_code: &str, mode: Mode, @@ -74254,7 +74473,7 @@ fn __action1631< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74262,7 +74481,7 @@ fn __action1631< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1391( + __action1393( source_code, mode, __temp0, @@ -74276,7 +74495,7 @@ fn __action1631< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1632< +fn __action1636< >( source_code: &str, mode: Mode, @@ -74293,7 +74512,7 @@ fn __action1632< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74302,7 +74521,7 @@ fn __action1632< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1391( + __action1393( source_code, mode, __temp0, @@ -74316,7 +74535,7 @@ fn __action1632< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1633< +fn __action1637< >( source_code: &str, mode: Mode, @@ -74329,13 +74548,13 @@ fn __action1633< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1392( + __action1394( source_code, mode, __temp0, @@ -74348,7 +74567,7 @@ fn __action1633< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1634< +fn __action1638< >( source_code: &str, mode: Mode, @@ -74363,7 +74582,7 @@ fn __action1634< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74371,7 +74590,7 @@ fn __action1634< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1392( + __action1394( source_code, mode, __temp0, @@ -74384,7 +74603,7 @@ fn __action1634< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1635< +fn __action1639< >( source_code: &str, mode: Mode, @@ -74400,7 +74619,7 @@ fn __action1635< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74409,7 +74628,7 @@ fn __action1635< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1392( + __action1394( source_code, mode, __temp0, @@ -74422,7 +74641,7 @@ fn __action1635< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1636< +fn __action1640< >( source_code: &str, mode: Mode, @@ -74437,13 +74656,13 @@ fn __action1636< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1393( + __action1395( source_code, mode, __temp0, @@ -74458,7 +74677,7 @@ fn __action1636< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1637< +fn __action1641< >( source_code: &str, mode: Mode, @@ -74475,7 +74694,7 @@ fn __action1637< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74483,7 +74702,7 @@ fn __action1637< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1393( + __action1395( source_code, mode, __temp0, @@ -74498,7 +74717,7 @@ fn __action1637< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1638< +fn __action1642< >( source_code: &str, mode: Mode, @@ -74516,7 +74735,7 @@ fn __action1638< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74525,7 +74744,7 @@ fn __action1638< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1393( + __action1395( source_code, mode, __temp0, @@ -74540,7 +74759,7 @@ fn __action1638< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1639< +fn __action1643< >( source_code: &str, mode: Mode, @@ -74554,13 +74773,13 @@ fn __action1639< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1394( + __action1396( source_code, mode, __temp0, @@ -74574,7 +74793,7 @@ fn __action1639< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1640< +fn __action1644< >( source_code: &str, mode: Mode, @@ -74590,7 +74809,7 @@ fn __action1640< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74598,7 +74817,7 @@ fn __action1640< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1394( + __action1396( source_code, mode, __temp0, @@ -74612,7 +74831,7 @@ fn __action1640< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1641< +fn __action1645< >( source_code: &str, mode: Mode, @@ -74629,7 +74848,7 @@ fn __action1641< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74638,7 +74857,7 @@ fn __action1641< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1394( + __action1396( source_code, mode, __temp0, @@ -74652,7 +74871,7 @@ fn __action1641< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1642< +fn __action1646< >( source_code: &str, mode: Mode, @@ -74664,13 +74883,13 @@ fn __action1642< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1395( + __action1397( source_code, mode, __temp0, @@ -74682,7 +74901,7 @@ fn __action1642< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1643< +fn __action1647< >( source_code: &str, mode: Mode, @@ -74696,7 +74915,7 @@ fn __action1643< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74704,7 +74923,7 @@ fn __action1643< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1395( + __action1397( source_code, mode, __temp0, @@ -74716,7 +74935,7 @@ fn __action1643< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1644< +fn __action1648< >( source_code: &str, mode: Mode, @@ -74731,7 +74950,7 @@ fn __action1644< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74740,7 +74959,7 @@ fn __action1644< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1395( + __action1397( source_code, mode, __temp0, @@ -74752,7 +74971,7 @@ fn __action1644< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1645< +fn __action1649< >( source_code: &str, mode: Mode, @@ -74763,13 +74982,13 @@ fn __action1645< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1396( + __action1398( source_code, mode, __temp0, @@ -74780,7 +74999,7 @@ fn __action1645< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1646< +fn __action1650< >( source_code: &str, mode: Mode, @@ -74793,7 +75012,7 @@ fn __action1646< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74801,7 +75020,7 @@ fn __action1646< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1396( + __action1398( source_code, mode, __temp0, @@ -74812,7 +75031,7 @@ fn __action1646< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1647< +fn __action1651< >( source_code: &str, mode: Mode, @@ -74826,7 +75045,7 @@ fn __action1647< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74835,7 +75054,7 @@ fn __action1647< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1396( + __action1398( source_code, mode, __temp0, @@ -74846,7 +75065,7 @@ fn __action1647< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1648< +fn __action1652< >( source_code: &str, mode: Mode, @@ -74859,13 +75078,13 @@ fn __action1648< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1397( + __action1399( source_code, mode, __temp0, @@ -74878,7 +75097,7 @@ fn __action1648< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1649< +fn __action1653< >( source_code: &str, mode: Mode, @@ -74893,7 +75112,7 @@ fn __action1649< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -74901,7 +75120,7 @@ fn __action1649< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1397( + __action1399( source_code, mode, __temp0, @@ -74914,7 +75133,7 @@ fn __action1649< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1650< +fn __action1654< >( source_code: &str, mode: Mode, @@ -74930,7 +75149,7 @@ fn __action1650< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -74939,7 +75158,7 @@ fn __action1650< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1397( + __action1399( source_code, mode, __temp0, @@ -74952,7 +75171,7 @@ fn __action1650< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1651< +fn __action1655< >( source_code: &str, mode: Mode, @@ -74964,13 +75183,13 @@ fn __action1651< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1398( + __action1400( source_code, mode, __temp0, @@ -74982,7 +75201,7 @@ fn __action1651< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1652< +fn __action1656< >( source_code: &str, mode: Mode, @@ -74996,7 +75215,7 @@ fn __action1652< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -75004,7 +75223,7 @@ fn __action1652< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1398( + __action1400( source_code, mode, __temp0, @@ -75016,7 +75235,7 @@ fn __action1652< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1653< +fn __action1657< >( source_code: &str, mode: Mode, @@ -75031,7 +75250,7 @@ fn __action1653< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -75040,7 +75259,7 @@ fn __action1653< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1398( + __action1400( source_code, mode, __temp0, @@ -75052,7 +75271,7 @@ fn __action1653< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1654< +fn __action1658< >( source_code: &str, mode: Mode, @@ -75061,13 +75280,13 @@ fn __action1654< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1399( + __action1401( source_code, mode, __temp0, @@ -75076,7 +75295,7 @@ fn __action1654< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1655< +fn __action1659< >( source_code: &str, mode: Mode, @@ -75087,7 +75306,7 @@ fn __action1655< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -75095,7 +75314,7 @@ fn __action1655< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1399( + __action1401( source_code, mode, __temp0, @@ -75104,7 +75323,7 @@ fn __action1655< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1656< +fn __action1660< >( source_code: &str, mode: Mode, @@ -75116,7 +75335,7 @@ fn __action1656< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -75125,7 +75344,7 @@ fn __action1656< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1399( + __action1401( source_code, mode, __temp0, @@ -75134,7 +75353,7 @@ fn __action1656< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1657< +fn __action1661< >( source_code: &str, mode: Mode, @@ -75146,13 +75365,13 @@ fn __action1657< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1400( + __action1402( source_code, mode, __temp0, @@ -75164,7 +75383,7 @@ fn __action1657< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1658< +fn __action1662< >( source_code: &str, mode: Mode, @@ -75178,7 +75397,7 @@ fn __action1658< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -75186,7 +75405,7 @@ fn __action1658< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1400( + __action1402( source_code, mode, __temp0, @@ -75198,7 +75417,7 @@ fn __action1658< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1659< +fn __action1663< >( source_code: &str, mode: Mode, @@ -75213,7 +75432,7 @@ fn __action1659< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -75222,7 +75441,7 @@ fn __action1659< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1400( + __action1402( source_code, mode, __temp0, @@ -75234,7 +75453,7 @@ fn __action1659< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1660< +fn __action1664< >( source_code: &str, mode: Mode, @@ -75245,13 +75464,13 @@ fn __action1660< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action443( + let __temp0 = __action446( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1401( + __action1403( source_code, mode, __temp0, @@ -75262,7 +75481,7 @@ fn __action1660< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1661< +fn __action1665< >( source_code: &str, mode: Mode, @@ -75275,7 +75494,7 @@ fn __action1661< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action698( + let __temp0 = __action701( source_code, mode, __0, @@ -75283,7 +75502,7 @@ fn __action1661< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1401( + __action1403( source_code, mode, __temp0, @@ -75294,7 +75513,7 @@ fn __action1661< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1662< +fn __action1666< >( source_code: &str, mode: Mode, @@ -75308,7 +75527,7 @@ fn __action1662< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action699( + let __temp0 = __action702( source_code, mode, __0, @@ -75317,7 +75536,7 @@ fn __action1662< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1401( + __action1403( source_code, mode, __temp0, @@ -75328,7 +75547,7 @@ fn __action1662< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1663< +fn __action1667< >( source_code: &str, mode: Mode, @@ -75343,13 +75562,13 @@ fn __action1663< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1420( + __action1422( source_code, mode, __temp0, @@ -75364,7 +75583,7 @@ fn __action1663< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1664< +fn __action1668< >( source_code: &str, mode: Mode, @@ -75381,7 +75600,7 @@ fn __action1664< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -75389,7 +75608,7 @@ fn __action1664< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1420( + __action1422( source_code, mode, __temp0, @@ -75404,7 +75623,7 @@ fn __action1664< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1665< +fn __action1669< >( source_code: &str, mode: Mode, @@ -75422,7 +75641,7 @@ fn __action1665< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -75431,7 +75650,7 @@ fn __action1665< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1420( + __action1422( source_code, mode, __temp0, @@ -75446,7 +75665,7 @@ fn __action1665< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1666< +fn __action1670< >( source_code: &str, mode: Mode, @@ -75460,13 +75679,13 @@ fn __action1666< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1421( + __action1423( source_code, mode, __temp0, @@ -75480,7 +75699,7 @@ fn __action1666< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1667< +fn __action1671< >( source_code: &str, mode: Mode, @@ -75496,7 +75715,7 @@ fn __action1667< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -75504,7 +75723,7 @@ fn __action1667< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1421( + __action1423( source_code, mode, __temp0, @@ -75518,7 +75737,7 @@ fn __action1667< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1668< +fn __action1672< >( source_code: &str, mode: Mode, @@ -75535,7 +75754,7 @@ fn __action1668< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -75544,7 +75763,7 @@ fn __action1668< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1421( + __action1423( source_code, mode, __temp0, @@ -75558,7 +75777,7 @@ fn __action1668< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1669< +fn __action1673< >( source_code: &str, mode: Mode, @@ -75574,13 +75793,13 @@ fn __action1669< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1422( + __action1424( source_code, mode, __temp0, @@ -75596,7 +75815,7 @@ fn __action1669< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1670< +fn __action1674< >( source_code: &str, mode: Mode, @@ -75614,7 +75833,7 @@ fn __action1670< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -75622,7 +75841,7 @@ fn __action1670< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1422( + __action1424( source_code, mode, __temp0, @@ -75638,7 +75857,7 @@ fn __action1670< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1671< +fn __action1675< >( source_code: &str, mode: Mode, @@ -75657,7 +75876,7 @@ fn __action1671< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -75666,7 +75885,7 @@ fn __action1671< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1422( + __action1424( source_code, mode, __temp0, @@ -75682,7 +75901,7 @@ fn __action1671< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1672< +fn __action1676< >( source_code: &str, mode: Mode, @@ -75697,13 +75916,13 @@ fn __action1672< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1423( + __action1425( source_code, mode, __temp0, @@ -75718,7 +75937,7 @@ fn __action1672< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1673< +fn __action1677< >( source_code: &str, mode: Mode, @@ -75735,7 +75954,7 @@ fn __action1673< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -75743,7 +75962,7 @@ fn __action1673< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1423( + __action1425( source_code, mode, __temp0, @@ -75758,7 +75977,7 @@ fn __action1673< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1674< +fn __action1678< >( source_code: &str, mode: Mode, @@ -75776,7 +75995,7 @@ fn __action1674< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -75785,7 +76004,7 @@ fn __action1674< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1423( + __action1425( source_code, mode, __temp0, @@ -75800,7 +76019,7 @@ fn __action1674< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1675< +fn __action1679< >( source_code: &str, mode: Mode, @@ -75813,13 +76032,13 @@ fn __action1675< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1424( + __action1426( source_code, mode, __temp0, @@ -75832,7 +76051,7 @@ fn __action1675< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1676< +fn __action1680< >( source_code: &str, mode: Mode, @@ -75847,7 +76066,7 @@ fn __action1676< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -75855,7 +76074,7 @@ fn __action1676< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1424( + __action1426( source_code, mode, __temp0, @@ -75868,7 +76087,7 @@ fn __action1676< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1677< +fn __action1681< >( source_code: &str, mode: Mode, @@ -75884,7 +76103,7 @@ fn __action1677< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -75893,7 +76112,7 @@ fn __action1677< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1424( + __action1426( source_code, mode, __temp0, @@ -75906,7 +76125,7 @@ fn __action1677< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1678< +fn __action1682< >( source_code: &str, mode: Mode, @@ -75918,13 +76137,13 @@ fn __action1678< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1425( + __action1427( source_code, mode, __temp0, @@ -75936,7 +76155,7 @@ fn __action1678< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1679< +fn __action1683< >( source_code: &str, mode: Mode, @@ -75950,7 +76169,7 @@ fn __action1679< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -75958,7 +76177,7 @@ fn __action1679< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1425( + __action1427( source_code, mode, __temp0, @@ -75970,7 +76189,7 @@ fn __action1679< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1680< +fn __action1684< >( source_code: &str, mode: Mode, @@ -75985,7 +76204,7 @@ fn __action1680< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -75994,7 +76213,7 @@ fn __action1680< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1425( + __action1427( source_code, mode, __temp0, @@ -76006,7 +76225,7 @@ fn __action1680< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1681< +fn __action1685< >( source_code: &str, mode: Mode, @@ -76020,13 +76239,13 @@ fn __action1681< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1426( + __action1428( source_code, mode, __temp0, @@ -76040,7 +76259,7 @@ fn __action1681< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1682< +fn __action1686< >( source_code: &str, mode: Mode, @@ -76056,7 +76275,7 @@ fn __action1682< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76064,7 +76283,7 @@ fn __action1682< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1426( + __action1428( source_code, mode, __temp0, @@ -76078,7 +76297,7 @@ fn __action1682< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1683< +fn __action1687< >( source_code: &str, mode: Mode, @@ -76095,7 +76314,7 @@ fn __action1683< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76104,7 +76323,7 @@ fn __action1683< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1426( + __action1428( source_code, mode, __temp0, @@ -76118,7 +76337,7 @@ fn __action1683< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1684< +fn __action1688< >( source_code: &str, mode: Mode, @@ -76131,13 +76350,13 @@ fn __action1684< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1427( + __action1429( source_code, mode, __temp0, @@ -76150,7 +76369,7 @@ fn __action1684< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1685< +fn __action1689< >( source_code: &str, mode: Mode, @@ -76165,7 +76384,7 @@ fn __action1685< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76173,7 +76392,7 @@ fn __action1685< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1427( + __action1429( source_code, mode, __temp0, @@ -76186,7 +76405,7 @@ fn __action1685< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1686< +fn __action1690< >( source_code: &str, mode: Mode, @@ -76202,7 +76421,7 @@ fn __action1686< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76211,7 +76430,7 @@ fn __action1686< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1427( + __action1429( source_code, mode, __temp0, @@ -76224,7 +76443,7 @@ fn __action1686< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1687< +fn __action1691< >( source_code: &str, mode: Mode, @@ -76234,13 +76453,13 @@ fn __action1687< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1428( + __action1430( source_code, mode, __temp0, @@ -76250,7 +76469,7 @@ fn __action1687< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1688< +fn __action1692< >( source_code: &str, mode: Mode, @@ -76262,7 +76481,7 @@ fn __action1688< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76270,7 +76489,7 @@ fn __action1688< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1428( + __action1430( source_code, mode, __temp0, @@ -76280,7 +76499,7 @@ fn __action1688< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1689< +fn __action1693< >( source_code: &str, mode: Mode, @@ -76293,7 +76512,7 @@ fn __action1689< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76302,7 +76521,7 @@ fn __action1689< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1428( + __action1430( source_code, mode, __temp0, @@ -76312,7 +76531,7 @@ fn __action1689< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1690< +fn __action1694< >( source_code: &str, mode: Mode, @@ -76326,13 +76545,13 @@ fn __action1690< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1429( + __action1431( source_code, mode, __temp0, @@ -76346,7 +76565,7 @@ fn __action1690< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1691< +fn __action1695< >( source_code: &str, mode: Mode, @@ -76362,7 +76581,7 @@ fn __action1691< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76370,7 +76589,7 @@ fn __action1691< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1429( + __action1431( source_code, mode, __temp0, @@ -76384,7 +76603,7 @@ fn __action1691< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1692< +fn __action1696< >( source_code: &str, mode: Mode, @@ -76401,7 +76620,7 @@ fn __action1692< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76410,7 +76629,7 @@ fn __action1692< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1429( + __action1431( source_code, mode, __temp0, @@ -76424,7 +76643,7 @@ fn __action1692< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1693< +fn __action1697< >( source_code: &str, mode: Mode, @@ -76437,13 +76656,13 @@ fn __action1693< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1430( + __action1432( source_code, mode, __temp0, @@ -76456,7 +76675,7 @@ fn __action1693< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1694< +fn __action1698< >( source_code: &str, mode: Mode, @@ -76471,7 +76690,7 @@ fn __action1694< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76479,7 +76698,7 @@ fn __action1694< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1430( + __action1432( source_code, mode, __temp0, @@ -76492,7 +76711,7 @@ fn __action1694< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1695< +fn __action1699< >( source_code: &str, mode: Mode, @@ -76508,7 +76727,7 @@ fn __action1695< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76517,7 +76736,7 @@ fn __action1695< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1430( + __action1432( source_code, mode, __temp0, @@ -76530,7 +76749,7 @@ fn __action1695< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1696< +fn __action1700< >( source_code: &str, mode: Mode, @@ -76545,13 +76764,13 @@ fn __action1696< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1431( + __action1433( source_code, mode, __temp0, @@ -76566,7 +76785,7 @@ fn __action1696< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1697< +fn __action1701< >( source_code: &str, mode: Mode, @@ -76583,7 +76802,7 @@ fn __action1697< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76591,7 +76810,7 @@ fn __action1697< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1431( + __action1433( source_code, mode, __temp0, @@ -76606,7 +76825,7 @@ fn __action1697< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1698< +fn __action1702< >( source_code: &str, mode: Mode, @@ -76624,7 +76843,7 @@ fn __action1698< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76633,7 +76852,7 @@ fn __action1698< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1431( + __action1433( source_code, mode, __temp0, @@ -76648,7 +76867,7 @@ fn __action1698< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1699< +fn __action1703< >( source_code: &str, mode: Mode, @@ -76662,13 +76881,13 @@ fn __action1699< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1432( + __action1434( source_code, mode, __temp0, @@ -76682,7 +76901,7 @@ fn __action1699< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1700< +fn __action1704< >( source_code: &str, mode: Mode, @@ -76698,7 +76917,7 @@ fn __action1700< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76706,7 +76925,7 @@ fn __action1700< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1432( + __action1434( source_code, mode, __temp0, @@ -76720,7 +76939,7 @@ fn __action1700< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1701< +fn __action1705< >( source_code: &str, mode: Mode, @@ -76737,7 +76956,7 @@ fn __action1701< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76746,7 +76965,7 @@ fn __action1701< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1432( + __action1434( source_code, mode, __temp0, @@ -76760,7 +76979,7 @@ fn __action1701< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1702< +fn __action1706< >( source_code: &str, mode: Mode, @@ -76772,13 +76991,13 @@ fn __action1702< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1433( + __action1435( source_code, mode, __temp0, @@ -76790,7 +77009,7 @@ fn __action1702< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1703< +fn __action1707< >( source_code: &str, mode: Mode, @@ -76804,7 +77023,7 @@ fn __action1703< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76812,7 +77031,7 @@ fn __action1703< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1433( + __action1435( source_code, mode, __temp0, @@ -76824,7 +77043,7 @@ fn __action1703< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1704< +fn __action1708< >( source_code: &str, mode: Mode, @@ -76839,7 +77058,7 @@ fn __action1704< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76848,7 +77067,7 @@ fn __action1704< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1433( + __action1435( source_code, mode, __temp0, @@ -76860,7 +77079,7 @@ fn __action1704< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1705< +fn __action1709< >( source_code: &str, mode: Mode, @@ -76871,13 +77090,13 @@ fn __action1705< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1434( + __action1436( source_code, mode, __temp0, @@ -76888,7 +77107,7 @@ fn __action1705< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1706< +fn __action1710< >( source_code: &str, mode: Mode, @@ -76901,7 +77120,7 @@ fn __action1706< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -76909,7 +77128,7 @@ fn __action1706< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1434( + __action1436( source_code, mode, __temp0, @@ -76920,7 +77139,7 @@ fn __action1706< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1707< +fn __action1711< >( source_code: &str, mode: Mode, @@ -76934,7 +77153,7 @@ fn __action1707< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -76943,7 +77162,7 @@ fn __action1707< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1434( + __action1436( source_code, mode, __temp0, @@ -76954,7 +77173,7 @@ fn __action1707< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1708< +fn __action1712< >( source_code: &str, mode: Mode, @@ -76967,13 +77186,13 @@ fn __action1708< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1435( + __action1437( source_code, mode, __temp0, @@ -76986,7 +77205,7 @@ fn __action1708< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1709< +fn __action1713< >( source_code: &str, mode: Mode, @@ -77001,7 +77220,7 @@ fn __action1709< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -77009,7 +77228,7 @@ fn __action1709< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1435( + __action1437( source_code, mode, __temp0, @@ -77022,7 +77241,7 @@ fn __action1709< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1710< +fn __action1714< >( source_code: &str, mode: Mode, @@ -77038,7 +77257,7 @@ fn __action1710< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -77047,7 +77266,7 @@ fn __action1710< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1435( + __action1437( source_code, mode, __temp0, @@ -77060,7 +77279,7 @@ fn __action1710< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1711< +fn __action1715< >( source_code: &str, mode: Mode, @@ -77072,13 +77291,13 @@ fn __action1711< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1436( + __action1438( source_code, mode, __temp0, @@ -77090,7 +77309,7 @@ fn __action1711< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1712< +fn __action1716< >( source_code: &str, mode: Mode, @@ -77104,7 +77323,7 @@ fn __action1712< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -77112,7 +77331,7 @@ fn __action1712< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1436( + __action1438( source_code, mode, __temp0, @@ -77124,7 +77343,7 @@ fn __action1712< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1713< +fn __action1717< >( source_code: &str, mode: Mode, @@ -77139,7 +77358,7 @@ fn __action1713< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -77148,7 +77367,7 @@ fn __action1713< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1436( + __action1438( source_code, mode, __temp0, @@ -77160,7 +77379,7 @@ fn __action1713< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1714< +fn __action1718< >( source_code: &str, mode: Mode, @@ -77169,13 +77388,13 @@ fn __action1714< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1437( + __action1439( source_code, mode, __temp0, @@ -77184,7 +77403,7 @@ fn __action1714< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1715< +fn __action1719< >( source_code: &str, mode: Mode, @@ -77195,7 +77414,7 @@ fn __action1715< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -77203,7 +77422,7 @@ fn __action1715< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1437( + __action1439( source_code, mode, __temp0, @@ -77212,7 +77431,7 @@ fn __action1715< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1716< +fn __action1720< >( source_code: &str, mode: Mode, @@ -77224,7 +77443,7 @@ fn __action1716< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -77233,7 +77452,7 @@ fn __action1716< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1437( + __action1439( source_code, mode, __temp0, @@ -77242,7 +77461,7 @@ fn __action1716< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1717< +fn __action1721< >( source_code: &str, mode: Mode, @@ -77254,13 +77473,13 @@ fn __action1717< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1438( + __action1440( source_code, mode, __temp0, @@ -77272,7 +77491,7 @@ fn __action1717< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1718< +fn __action1722< >( source_code: &str, mode: Mode, @@ -77286,7 +77505,7 @@ fn __action1718< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -77294,7 +77513,7 @@ fn __action1718< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1438( + __action1440( source_code, mode, __temp0, @@ -77306,7 +77525,7 @@ fn __action1718< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1719< +fn __action1723< >( source_code: &str, mode: Mode, @@ -77321,7 +77540,7 @@ fn __action1719< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -77330,7 +77549,7 @@ fn __action1719< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1438( + __action1440( source_code, mode, __temp0, @@ -77342,7 +77561,7 @@ fn __action1719< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1720< +fn __action1724< >( source_code: &str, mode: Mode, @@ -77353,13 +77572,13 @@ fn __action1720< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action451( + let __temp0 = __action454( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1439( + __action1441( source_code, mode, __temp0, @@ -77370,7 +77589,7 @@ fn __action1720< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1721< +fn __action1725< >( source_code: &str, mode: Mode, @@ -77383,7 +77602,7 @@ fn __action1721< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action706( + let __temp0 = __action709( source_code, mode, __0, @@ -77391,7 +77610,7 @@ fn __action1721< __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1439( + __action1441( source_code, mode, __temp0, @@ -77402,7 +77621,7 @@ fn __action1721< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1722< +fn __action1726< >( source_code: &str, mode: Mode, @@ -77416,7 +77635,7 @@ fn __action1722< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action707( + let __temp0 = __action710( source_code, mode, __0, @@ -77425,7 +77644,7 @@ fn __action1722< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1439( + __action1441( source_code, mode, __temp0, @@ -77436,7 +77655,7 @@ fn __action1722< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1723< +fn __action1727< >( source_code: &str, mode: Mode, @@ -77444,18 +77663,18 @@ fn __action1723< __1: (TextSize, ast::Parameters, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, core::option::Option<(String, bool)>, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Result> + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Result> { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action278( + let __temp0 = __action283( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1345( + __action1347( source_code, mode, __0, @@ -77468,26 +77687,26 @@ fn __action1723< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1724< +fn __action1728< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, core::option::Option<(String, bool)>, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Result> + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action279( + let __temp0 = __action284( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1345( + __action1347( source_code, mode, __0, @@ -77500,25 +77719,25 @@ fn __action1724< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1725< +fn __action1729< >( source_code: &str, mode: Mode, - __0: (TextSize, core::option::Option, TextSize), + __0: (TextSize, core::option::Option, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option, TextSize), - __3: (TextSize, Option, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, core::option::Option, TextSize), + __3: (TextSize, Option, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action272( + let __temp0 = __action277( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1491( + __action1495( source_code, mode, __0, @@ -77530,25 +77749,25 @@ fn __action1725< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1726< +fn __action1730< >( source_code: &str, mode: Mode, - __0: (TextSize, core::option::Option, TextSize), + __0: (TextSize, core::option::Option, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, core::option::Option, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action273( + let __temp0 = __action278( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1491( + __action1495( source_code, mode, __0, @@ -77560,25 +77779,25 @@ fn __action1726< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1727< +fn __action1731< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, ast::Suite, TextSize), ) -> ast::ExceptHandler { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action322( + let __temp0 = __action327( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action791( + __action792( source_code, mode, __0, @@ -77590,7 +77809,7 @@ fn __action1727< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1728< +fn __action1732< >( source_code: &str, mode: Mode, @@ -77601,14 +77820,14 @@ fn __action1728< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action323( + let __temp0 = __action328( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action791( + __action792( source_code, mode, __0, @@ -77620,23 +77839,23 @@ fn __action1728< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1729< +fn __action1733< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Option + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Option { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action322( + let __temp0 = __action327( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action929( + __action930( source_code, mode, __0, @@ -77646,23 +77865,23 @@ fn __action1729< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1730< +fn __action1734< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> Option +) -> Option { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action323( + let __temp0 = __action328( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action929( + __action930( source_code, mode, __0, @@ -77672,33 +77891,33 @@ fn __action1730< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1731< +fn __action1735< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), - __3: (TextSize, Option, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __3: (TextSize, Option, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.2; let __start1 = __2.0; let __end1 = __2.2; - let __temp0 = __action322( + let __temp0 = __action327( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action322( + let __temp1 = __action327( source_code, mode, __2, ); let __temp1 = (__start1, __temp1, __end1); - __action1725( + __action1729( source_code, mode, __temp0, @@ -77710,33 +77929,33 @@ fn __action1731< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1732< +fn __action1736< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, Option, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, Option, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.2; let __start1 = __1.2; let __end1 = __2.0; - let __temp0 = __action322( + let __temp0 = __action327( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action323( + let __temp1 = __action328( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action1725( + __action1729( source_code, mode, __temp0, @@ -77748,33 +77967,33 @@ fn __action1732< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1733< +fn __action1737< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), - __2: (TextSize, Option, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __2: (TextSize, Option, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; let __start1 = __1.0; let __end1 = __1.2; - let __temp0 = __action323( + let __temp0 = __action328( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action322( + let __temp1 = __action327( source_code, mode, __1, ); let __temp1 = (__start1, __temp1, __end1); - __action1725( + __action1729( source_code, mode, __temp0, @@ -77786,33 +78005,33 @@ fn __action1733< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1734< +fn __action1738< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, Option, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, Option, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; let __start1 = __0.2; let __end1 = __1.0; - let __temp0 = __action323( + let __temp0 = __action328( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action323( + let __temp1 = __action328( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action1725( + __action1729( source_code, mode, __temp0, @@ -77824,32 +78043,32 @@ fn __action1734< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1735< +fn __action1739< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.2; let __start1 = __2.0; let __end1 = __2.2; - let __temp0 = __action322( + let __temp0 = __action327( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action322( + let __temp1 = __action327( source_code, mode, __2, ); let __temp1 = (__start1, __temp1, __end1); - __action1726( + __action1730( source_code, mode, __temp0, @@ -77860,32 +78079,32 @@ fn __action1735< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1736< +fn __action1740< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.2; let __start1 = __1.2; let __end1 = __1.2; - let __temp0 = __action322( + let __temp0 = __action327( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action323( + let __temp1 = __action328( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action1726( + __action1730( source_code, mode, __temp0, @@ -77896,32 +78115,32 @@ fn __action1736< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1737< +fn __action1741< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; let __start1 = __1.0; let __end1 = __1.2; - let __temp0 = __action323( + let __temp0 = __action328( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action322( + let __temp1 = __action327( source_code, mode, __1, ); let __temp1 = (__start1, __temp1, __end1); - __action1726( + __action1730( source_code, mode, __temp0, @@ -77932,32 +78151,32 @@ fn __action1737< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1738< +fn __action1742< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.0; let __start1 = __0.2; let __end1 = __0.2; - let __temp0 = __action323( + let __temp0 = __action328( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action323( + let __temp1 = __action328( source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action1726( + __action1730( source_code, mode, __temp0, @@ -77968,15 +78187,15 @@ fn __action1738< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1739< +fn __action1743< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, ast::Suite, TextSize), __7: (TextSize, token::Tok, TextSize), @@ -77986,13 +78205,13 @@ fn __action1739< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1124( + __action1127( source_code, mode, __0, @@ -78010,28 +78229,28 @@ fn __action1739< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1740< +fn __action1744< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1125( + __action1128( source_code, mode, __0, @@ -78046,14 +78265,14 @@ fn __action1740< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1741< +fn __action1745< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, ast::Suite, TextSize), __6: (TextSize, token::Tok, TextSize), @@ -78063,13 +78282,13 @@ fn __action1741< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1126( + __action1129( source_code, mode, __0, @@ -78086,27 +78305,27 @@ fn __action1741< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1742< +fn __action1746< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1127( + __action1130( source_code, mode, __0, @@ -78120,22 +78339,22 @@ fn __action1742< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1743< +fn __action1747< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> core::option::Option + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> core::option::Option { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action396( + __action399( source_code, mode, __temp0, @@ -78144,16 +78363,16 @@ fn __action1743< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1744< +fn __action1748< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __0, @@ -78168,16 +78387,16 @@ fn __action1744< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1745< +fn __action1749< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __0, @@ -78192,23 +78411,23 @@ fn __action1745< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1746< +fn __action1750< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Mod { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1500( + __action1504( source_code, mode, __0, @@ -78218,24 +78437,24 @@ fn __action1746< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1747< +fn __action1751< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __2: (TextSize, alloc::vec::Vec, TextSize), ) -> ast::Mod { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action232( + let __temp0 = __action235( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1501( + __action1505( source_code, mode, __0, @@ -78246,23 +78465,23 @@ fn __action1747< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1748< +fn __action1752< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1743( + let __temp0 = __action1747( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1320( + __action1322( source_code, mode, __0, @@ -78272,7 +78491,7 @@ fn __action1748< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1749< +fn __action1753< >( source_code: &str, mode: Mode, @@ -78281,14 +78500,14 @@ fn __action1749< { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action397( + let __temp0 = __action400( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1320( + __action1322( source_code, mode, __0, @@ -78298,23 +78517,23 @@ fn __action1749< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1750< +fn __action1754< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> ast::ParenthesizedExpr + __1: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> crate::parser::ParenthesizedExpr { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1743( + let __temp0 = __action1747( source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1525( + __action1529( source_code, mode, __0, @@ -78324,23 +78543,23 @@ fn __action1750< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1751< +fn __action1755< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), -) -> ast::ParenthesizedExpr +) -> crate::parser::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action397( + let __temp0 = __action400( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1525( + __action1529( source_code, mode, __0, @@ -78350,22 +78569,22 @@ fn __action1751< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1752< +fn __action1756< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1745( + let __temp0 = __action1749( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1529( + __action1533( source_code, mode, __temp0, @@ -78374,23 +78593,23 @@ fn __action1752< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1753< +fn __action1757< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), - __1: (TextSize, alloc::vec::Vec, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1745( + let __temp0 = __action1749( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1530( + __action1534( source_code, mode, __temp0, @@ -78400,24 +78619,24 @@ fn __action1753< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1754< +fn __action1758< >( source_code: &str, mode: Mode, - __0: (TextSize, ast::ParenthesizedExpr, TextSize), + __0: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1745( + let __temp0 = __action1749( source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1310( + __action1311( source_code, mode, __temp0, @@ -78428,7 +78647,7 @@ fn __action1754< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1755< +fn __action1759< >( source_code: &str, mode: Mode, @@ -78442,13 +78661,13 @@ fn __action1755< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1555( + __action1559( source_code, mode, __0, @@ -78462,7 +78681,7 @@ fn __action1755< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1756< +fn __action1760< >( source_code: &str, mode: Mode, @@ -78475,14 +78694,14 @@ fn __action1756< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1555( + __action1559( source_code, mode, __0, @@ -78496,7 +78715,7 @@ fn __action1756< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1757< +fn __action1761< >( source_code: &str, mode: Mode, @@ -78511,13 +78730,13 @@ fn __action1757< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1556( + __action1560( source_code, mode, __0, @@ -78532,7 +78751,7 @@ fn __action1757< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1758< +fn __action1762< >( source_code: &str, mode: Mode, @@ -78546,14 +78765,14 @@ fn __action1758< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1556( + __action1560( source_code, mode, __0, @@ -78568,7 +78787,7 @@ fn __action1758< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1759< +fn __action1763< >( source_code: &str, mode: Mode, @@ -78581,13 +78800,13 @@ fn __action1759< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1557( + __action1561( source_code, mode, __0, @@ -78600,7 +78819,7 @@ fn __action1759< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1760< +fn __action1764< >( source_code: &str, mode: Mode, @@ -78612,14 +78831,14 @@ fn __action1760< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1557( + __action1561( source_code, mode, __0, @@ -78632,7 +78851,7 @@ fn __action1760< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1761< +fn __action1765< >( source_code: &str, mode: Mode, @@ -78646,13 +78865,13 @@ fn __action1761< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1558( + __action1562( source_code, mode, __0, @@ -78666,7 +78885,7 @@ fn __action1761< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1762< +fn __action1766< >( source_code: &str, mode: Mode, @@ -78679,14 +78898,14 @@ fn __action1762< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1558( + __action1562( source_code, mode, __0, @@ -78700,7 +78919,7 @@ fn __action1762< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1763< +fn __action1767< >( source_code: &str, mode: Mode, @@ -78710,20 +78929,20 @@ fn __action1763< __3: (TextSize, ast::TypeParams, TextSize), __4: (TextSize, ast::Parameters, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::ParenthesizedExpr, TextSize), + __6: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __7: (TextSize, token::Tok, TextSize), __8: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1559( + __action1563( source_code, mode, __0, @@ -78740,7 +78959,7 @@ fn __action1763< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1764< +fn __action1768< >( source_code: &str, mode: Mode, @@ -78749,21 +78968,21 @@ fn __action1764< __2: (TextSize, ast::Identifier, TextSize), __3: (TextSize, ast::Parameters, TextSize), __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, ast::ParenthesizedExpr, TextSize), + __5: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1559( + __action1563( source_code, mode, __0, @@ -78780,7 +78999,7 @@ fn __action1764< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1765< +fn __action1769< >( source_code: &str, mode: Mode, @@ -78791,20 +79010,20 @@ fn __action1765< __4: (TextSize, ast::TypeParams, TextSize), __5: (TextSize, ast::Parameters, TextSize), __6: (TextSize, token::Tok, TextSize), - __7: (TextSize, ast::ParenthesizedExpr, TextSize), + __7: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __8: (TextSize, token::Tok, TextSize), __9: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1560( + __action1564( source_code, mode, __0, @@ -78822,7 +79041,7 @@ fn __action1765< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1766< +fn __action1770< >( source_code: &str, mode: Mode, @@ -78832,21 +79051,21 @@ fn __action1766< __3: (TextSize, ast::Identifier, TextSize), __4: (TextSize, ast::Parameters, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::ParenthesizedExpr, TextSize), + __6: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __7: (TextSize, token::Tok, TextSize), __8: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1560( + __action1564( source_code, mode, __0, @@ -78864,7 +79083,7 @@ fn __action1766< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1767< +fn __action1771< >( source_code: &str, mode: Mode, @@ -78879,13 +79098,13 @@ fn __action1767< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1561( + __action1565( source_code, mode, __0, @@ -78900,7 +79119,7 @@ fn __action1767< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1768< +fn __action1772< >( source_code: &str, mode: Mode, @@ -78914,14 +79133,14 @@ fn __action1768< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1561( + __action1565( source_code, mode, __0, @@ -78936,7 +79155,7 @@ fn __action1768< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1769< +fn __action1773< >( source_code: &str, mode: Mode, @@ -78952,13 +79171,13 @@ fn __action1769< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1562( + __action1566( source_code, mode, __0, @@ -78974,7 +79193,7 @@ fn __action1769< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1770< +fn __action1774< >( source_code: &str, mode: Mode, @@ -78989,14 +79208,14 @@ fn __action1770< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1562( + __action1566( source_code, mode, __0, @@ -79012,7 +79231,7 @@ fn __action1770< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1771< +fn __action1775< >( source_code: &str, mode: Mode, @@ -79021,20 +79240,20 @@ fn __action1771< __2: (TextSize, ast::TypeParams, TextSize), __3: (TextSize, ast::Parameters, TextSize), __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, ast::ParenthesizedExpr, TextSize), + __5: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1563( + __action1567( source_code, mode, __0, @@ -79050,7 +79269,7 @@ fn __action1771< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1772< +fn __action1776< >( source_code: &str, mode: Mode, @@ -79058,21 +79277,21 @@ fn __action1772< __1: (TextSize, ast::Identifier, TextSize), __2: (TextSize, ast::Parameters, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __5: (TextSize, token::Tok, TextSize), __6: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1563( + __action1567( source_code, mode, __0, @@ -79088,7 +79307,7 @@ fn __action1772< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1773< +fn __action1777< >( source_code: &str, mode: Mode, @@ -79098,20 +79317,20 @@ fn __action1773< __3: (TextSize, ast::TypeParams, TextSize), __4: (TextSize, ast::Parameters, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, ast::ParenthesizedExpr, TextSize), + __6: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __7: (TextSize, token::Tok, TextSize), __8: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1564( + __action1568( source_code, mode, __0, @@ -79128,7 +79347,7 @@ fn __action1773< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1774< +fn __action1778< >( source_code: &str, mode: Mode, @@ -79137,21 +79356,21 @@ fn __action1774< __2: (TextSize, ast::Identifier, TextSize), __3: (TextSize, ast::Parameters, TextSize), __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, ast::ParenthesizedExpr, TextSize), + __5: (TextSize, crate::parser::ParenthesizedExpr, TextSize), __6: (TextSize, token::Tok, TextSize), __7: (TextSize, ast::Suite, TextSize), ) -> ast::Stmt { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1564( + __action1568( source_code, mode, __0, @@ -79168,7 +79387,7 @@ fn __action1774< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1775< +fn __action1779< >( source_code: &str, mode: Mode, @@ -79182,13 +79401,13 @@ fn __action1775< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1565( + __action1569( source_code, mode, __0, @@ -79202,7 +79421,7 @@ fn __action1775< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1776< +fn __action1780< >( source_code: &str, mode: Mode, @@ -79215,14 +79434,14 @@ fn __action1776< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1565( + __action1569( source_code, mode, __0, @@ -79236,7 +79455,7 @@ fn __action1776< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1777< +fn __action1781< >( source_code: &str, mode: Mode, @@ -79251,13 +79470,13 @@ fn __action1777< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1566( + __action1570( source_code, mode, __0, @@ -79272,7 +79491,7 @@ fn __action1777< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1778< +fn __action1782< >( source_code: &str, mode: Mode, @@ -79286,14 +79505,14 @@ fn __action1778< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1566( + __action1570( source_code, mode, __0, @@ -79308,7 +79527,7 @@ fn __action1778< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1779< +fn __action1783< >( source_code: &str, mode: Mode, @@ -79316,18 +79535,18 @@ fn __action1779< __1: (TextSize, ast::Expr, TextSize), __2: (TextSize, ast::TypeParams, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action304( + let __temp0 = __action309( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1511( + __action1515( source_code, mode, __0, @@ -79340,26 +79559,26 @@ fn __action1779< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1780< +fn __action1784< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Expr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action305( + let __temp0 = __action310( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1511( + __action1515( source_code, mode, __0, @@ -79372,7 +79591,7 @@ fn __action1780< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1781< +fn __action1785< >( source_code: &str, mode: Mode, @@ -79380,18 +79599,18 @@ fn __action1781< __1: (TextSize, ast::Parameters, TextSize), __2: (TextSize, token::Tok, TextSize), __3: (TextSize, (String, bool), TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Result> + __4: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Result> { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action276( + let __temp0 = __action281( source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1723( + __action1727( source_code, mode, __0, @@ -79404,26 +79623,26 @@ fn __action1781< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1782< +fn __action1786< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameters, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Result> + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Result> { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action277( + let __temp0 = __action282( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1723( + __action1727( source_code, mode, __0, @@ -79436,25 +79655,25 @@ fn __action1782< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1783< +fn __action1787< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), __2: (TextSize, (String, bool), TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Result> + __3: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Result> { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action276( + let __temp0 = __action281( source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1724( + __action1728( source_code, mode, __0, @@ -79466,25 +79685,25 @@ fn __action1783< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1784< +fn __action1788< >( source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> Result> + __2: (TextSize, crate::parser::ParenthesizedExpr, TextSize), +) -> Result> { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action277( + let __temp0 = __action282( source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1724( + __action1728( source_code, mode, __0, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__invalid__tests__ok_attribute_weird.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__invalid__tests__ok_attribute_weird.snap index 8848b18979cd0..a8492db558afb 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__invalid__tests__ok_attribute_weird.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__invalid__tests__ok_attribute_weird.snap @@ -14,9 +14,15 @@ Ok( value: StringLiteral( ExprStringLiteral { range: 0..5, - value: "foo", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..5, + value: "foo", + unicode: false, + }, + ), + }, }, ), attr: Identifier { diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__match_softkeyword_in_notebook.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__match_softkeyword_in_notebook.snap new file mode 100644 index 0000000000000..0512714bd466a --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__match_softkeyword_in_notebook.snap @@ -0,0 +1,66 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_jupyter_source(source) +--- +[ + ( + Match, + 0..5, + ), + ( + Name { + name: "foo", + }, + 6..9, + ), + ( + Colon, + 9..10, + ), + ( + Newline, + 10..11, + ), + ( + Indent, + 11..15, + ), + ( + Case, + 15..19, + ), + ( + Name { + name: "bar", + }, + 20..23, + ), + ( + Colon, + 23..24, + ), + ( + Newline, + 24..25, + ), + ( + Indent, + 25..33, + ), + ( + Pass, + 33..37, + ), + ( + Newline, + 37..37, + ), + ( + Dedent, + 37..37, + ), + ( + Dedent, + 37..37, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__dict_unpacking.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__dict_unpacking.snap index 7e5c892feac09..cb0da9427c71a 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__dict_unpacking.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__dict_unpacking.snap @@ -10,9 +10,15 @@ Dict( StringLiteral( ExprStringLiteral { range: 1..4, - value: "a", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 1..4, + value: "a", + unicode: false, + }, + ), + }, }, ), ), @@ -21,9 +27,15 @@ Dict( StringLiteral( ExprStringLiteral { range: 16..19, - value: "d", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 16..19, + value: "d", + unicode: false, + }, + ), + }, }, ), ), @@ -32,9 +44,15 @@ Dict( StringLiteral( ExprStringLiteral { range: 6..9, - value: "b", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 6..9, + value: "b", + unicode: false, + }, + ), + }, }, ), Name( @@ -47,9 +65,15 @@ Dict( StringLiteral( ExprStringLiteral { range: 21..24, - value: "e", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 21..24, + value: "e", + unicode: false, + }, + ), + }, }, ), ], diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings.snap index 7263bb506e71f..58c33b7302c9d 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings.snap @@ -9,25 +9,39 @@ expression: parse_ast value: FString( ExprFString { range: 0..9, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..8, - value: StringLiteral( - ExprStringLiteral { - range: 3..7, - value: " f", - unicode: false, - implicit_concatenated: false, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..9, + elements: [ + Expression( + FStringExpressionElement { + range: 2..8, + expression: StringLiteral( + ExprStringLiteral { + range: 3..7, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 3..7, + value: " f", + unicode: false, + }, + ), + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -38,24 +52,32 @@ expression: parse_ast value: FString( ExprFString { range: 10..20, - values: [ - FormattedValue( - ExprFormattedValue { - range: 12..19, - value: Name( - ExprName { - range: 13..16, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: Str, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 10..20, + elements: [ + Expression( + FStringExpressionElement { + range: 12..19, + expression: Name( + ExprName { + range: 13..16, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: Str, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -66,33 +88,41 @@ expression: parse_ast value: FString( ExprFString { range: 21..28, - values: [ - FormattedValue( - ExprFormattedValue { - range: 23..27, - value: Tuple( - ExprTuple { - range: 24..26, - elts: [ - NumberLiteral( - ExprNumberLiteral { - range: 24..25, - value: Int( - 3, - ), - }, - ), - ], - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 21..28, + elements: [ + Expression( + FStringExpressionElement { + range: 23..27, + expression: Tuple( + ExprTuple { + range: 24..26, + elts: [ + NumberLiteral( + ExprNumberLiteral { + range: 24..25, + value: Int( + 3, + ), + }, + ), + ], + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -103,51 +133,56 @@ expression: parse_ast value: FString( ExprFString { range: 29..39, - values: [ - FormattedValue( - ExprFormattedValue { - range: 31..38, - value: Compare( - ExprCompare { - range: 32..36, - left: NumberLiteral( - ExprNumberLiteral { - range: 32..33, - value: Int( - 3, + value: FStringValue { + inner: Single( + FString( + FString { + range: 29..39, + elements: [ + Expression( + FStringExpressionElement { + range: 31..38, + expression: Compare( + ExprCompare { + range: 32..36, + left: NumberLiteral( + ExprNumberLiteral { + range: 32..33, + value: Int( + 3, + ), + }, + ), + ops: [ + NotEq, + ], + comparators: [ + NumberLiteral( + ExprNumberLiteral { + range: 35..36, + value: Int( + 4, + ), + }, + ), + ], + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { + range: 37..37, + elements: [], + }, ), }, ), - ops: [ - NotEq, - ], - comparators: [ - NumberLiteral( - ExprNumberLiteral { - range: 35..36, - value: Int( - 4, - ), - }, - ), - ], - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 37..37, - values: [], - implicit_concatenated: false, - }, - ), - ), - }, + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -158,58 +193,67 @@ expression: parse_ast value: FString( ExprFString { range: 40..55, - values: [ - FormattedValue( - ExprFormattedValue { - range: 42..54, - value: NumberLiteral( - ExprNumberLiteral { - range: 43..44, - value: Int( - 3, - ), - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 45..53, - values: [ - FormattedValue( - ExprFormattedValue { - range: 45..50, - value: StringLiteral( - ExprStringLiteral { - range: 46..49, - value: "}", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 40..55, + elements: [ + Expression( + FStringExpressionElement { + range: 42..54, + expression: NumberLiteral( + ExprNumberLiteral { + range: 43..44, + value: Int( + 3, ), - debug_text: None, - conversion: None, - format_spec: None, }, ), - StringLiteral( - ExprStringLiteral { - range: 50..53, - value: ">10", - unicode: false, - implicit_concatenated: false, + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { + range: 45..53, + elements: [ + Expression( + FStringExpressionElement { + range: 45..50, + expression: StringLiteral( + ExprStringLiteral { + range: 46..49, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 46..49, + value: "}", + unicode: false, + }, + ), + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 50..53, + value: ">10", + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -220,58 +264,67 @@ expression: parse_ast value: FString( ExprFString { range: 56..71, - values: [ - FormattedValue( - ExprFormattedValue { - range: 58..70, - value: NumberLiteral( - ExprNumberLiteral { - range: 59..60, - value: Int( - 3, - ), - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 61..69, - values: [ - FormattedValue( - ExprFormattedValue { - range: 61..66, - value: StringLiteral( - ExprStringLiteral { - range: 62..65, - value: "{", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 56..71, + elements: [ + Expression( + FStringExpressionElement { + range: 58..70, + expression: NumberLiteral( + ExprNumberLiteral { + range: 59..60, + value: Int( + 3, ), - debug_text: None, - conversion: None, - format_spec: None, }, ), - StringLiteral( - ExprStringLiteral { - range: 66..69, - value: ">10", - unicode: false, - implicit_concatenated: false, + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { + range: 61..69, + elements: [ + Expression( + FStringExpressionElement { + range: 61..66, + expression: StringLiteral( + ExprStringLiteral { + range: 62..65, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 62..65, + value: "{", + unicode: false, + }, + ), + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 66..69, + value: ">10", + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -282,29 +335,37 @@ expression: parse_ast value: FString( ExprFString { range: 72..86, - values: [ - FormattedValue( - ExprFormattedValue { - range: 74..85, - value: Name( - ExprName { - range: 77..80, - id: "foo", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: " ", - trailing: " = ", - }, - ), - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 72..86, + elements: [ + Expression( + FStringExpressionElement { + range: 74..85, + expression: Name( + ExprName { + range: 77..80, + id: "foo", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: " ", + trailing: " = ", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -315,46 +376,49 @@ expression: parse_ast value: FString( ExprFString { range: 87..107, - values: [ - FormattedValue( - ExprFormattedValue { - range: 89..106, - value: Name( - ExprName { - range: 92..95, - id: "foo", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: " ", - trailing: " = ", - }, - ), - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 100..105, - values: [ - StringLiteral( - ExprStringLiteral { + value: FStringValue { + inner: Single( + FString( + FString { + range: 87..107, + elements: [ + Expression( + FStringExpressionElement { + range: 89..106, + expression: Name( + ExprName { + range: 92..95, + id: "foo", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: " ", + trailing: " = ", + }, + ), + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 100..105, - value: ".3f ", - unicode: false, - implicit_concatenated: false, + elements: [ + Literal( + FStringLiteralElement { + range: 100..105, + value: ".3f ", + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -365,29 +429,37 @@ expression: parse_ast value: FString( ExprFString { range: 108..126, - values: [ - FormattedValue( - ExprFormattedValue { - range: 110..125, - value: Name( - ExprName { - range: 113..116, - id: "foo", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: " ", - trailing: " = ", - }, - ), - conversion: Str, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 108..126, + elements: [ + Expression( + FStringExpressionElement { + range: 110..125, + expression: Name( + ExprName { + range: 113..116, + id: "foo", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: " ", + trailing: " = ", + }, + ), + conversion: Str, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -398,46 +470,54 @@ expression: parse_ast value: FString( ExprFString { range: 127..143, - values: [ - FormattedValue( - ExprFormattedValue { - range: 129..142, - value: Tuple( - ExprTuple { - range: 132..136, - elts: [ - NumberLiteral( - ExprNumberLiteral { - range: 132..133, - value: Int( - 1, - ), - }, - ), - NumberLiteral( - ExprNumberLiteral { - range: 135..136, - value: Int( - 2, - ), - }, - ), - ], - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: " ", - trailing: " = ", - }, - ), - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 127..143, + elements: [ + Expression( + FStringExpressionElement { + range: 129..142, + expression: Tuple( + ExprTuple { + range: 132..136, + elts: [ + NumberLiteral( + ExprNumberLiteral { + range: 132..133, + value: Int( + 1, + ), + }, + ), + NumberLiteral( + ExprNumberLiteral { + range: 135..136, + value: Int( + 2, + ), + }, + ), + ], + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: " ", + trailing: " = ", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -448,80 +528,86 @@ expression: parse_ast value: FString( ExprFString { range: 144..170, - values: [ - FormattedValue( - ExprFormattedValue { - range: 146..169, - value: FString( - ExprFString { - range: 147..163, - values: [ - FormattedValue( - ExprFormattedValue { - range: 149..162, - value: NumberLiteral( - ExprNumberLiteral { - range: 150..156, - value: Float( - 3.1415, + value: FStringValue { + inner: Single( + FString( + FString { + range: 144..170, + elements: [ + Expression( + FStringExpressionElement { + range: 146..169, + expression: FString( + ExprFString { + range: 147..163, + value: FStringValue { + inner: Single( + FString( + FString { + range: 147..163, + elements: [ + Expression( + FStringExpressionElement { + range: 149..162, + expression: NumberLiteral( + ExprNumberLiteral { + range: 150..156, + value: Float( + 3.1415, + ), + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: Some( + FStringFormatSpec { + range: 158..161, + elements: [ + Literal( + FStringLiteralElement { + range: 158..161, + value: ".1f", + }, + ), + ], + }, + ), + }, + ), + ], + }, + ), ), }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 158..161, - values: [ - StringLiteral( - ExprStringLiteral { - range: 158..161, - value: ".1f", - unicode: false, - implicit_concatenated: false, - }, - ), - ], - implicit_concatenated: false, - }, - ), - ), - }, - ), - ], - implicit_concatenated: false, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 164..168, - values: [ - StringLiteral( - ExprStringLiteral { + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 164..168, - value: "*^20", - unicode: false, - implicit_concatenated: false, + elements: [ + Literal( + FStringLiteralElement { + range: 164..168, + value: "*^20", + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -537,53 +623,73 @@ expression: parse_ast FString( ExprFString { range: 173..201, - values: [ - StringLiteral( - ExprStringLiteral { - range: 174..186, - value: "foo bar ", - unicode: false, - implicit_concatenated: true, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 186..193, - value: BinOp( - ExprBinOp { - range: 187..192, - left: Name( - ExprName { - range: 187..188, - id: "x", - ctx: Load, - }, - ), - op: Add, - right: Name( - ExprName { - range: 191..192, - id: "y", - ctx: Load, - }, - ), + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 173..179, + value: "foo ", + unicode: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 193..200, - value: " baz", - unicode: false, - implicit_concatenated: true, - }, + FString( + FString { + range: 180..195, + elements: [ + Literal( + FStringLiteralElement { + range: 182..186, + value: "bar ", + }, + ), + Expression( + FStringExpressionElement { + range: 186..193, + expression: BinOp( + ExprBinOp { + range: 187..192, + left: Name( + ExprName { + range: 187..188, + id: "x", + ctx: Load, + }, + ), + op: Add, + right: Name( + ExprName { + range: 191..192, + id: "y", + ctx: Load, + }, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 193..194, + value: " ", + }, + ), + ], + }, + ), + Literal( + StringLiteral { + range: 196..201, + value: "baz", + unicode: false, + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), ), @@ -621,9 +727,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 227..232, - value: "one", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 227..232, + value: "one", + unicode: false, + }, + ), + }, }, ), }, @@ -645,9 +757,25 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 256..284, - value: "implicitly concatenated", - unicode: false, - implicit_concatenated: true, + value: StringLiteralValue { + inner: Concatenated( + ConcatenatedStringLiteral { + strings: [ + StringLiteral { + range: 256..269, + value: "implicitly ", + unicode: false, + }, + StringLiteral { + range: 270..284, + value: "concatenated", + unicode: false, + }, + ], + value: "implicitly concatenated", + }, + ), + }, }, ), }, @@ -670,72 +798,71 @@ expression: parse_ast value: FString( ExprFString { range: 300..317, - values: [ - StringLiteral( - ExprStringLiteral { - range: 302..303, - value: "\\", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 303..308, - value: Name( - ExprName { - range: 304..307, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 308..309, - value: "\\", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 309..316, - value: Name( - ExprName { - range: 310..313, - id: "bar", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 314..315, - values: [ - StringLiteral( - ExprStringLiteral { + value: FStringValue { + inner: Single( + FString( + FString { + range: 300..317, + elements: [ + Literal( + FStringLiteralElement { + range: 302..303, + value: "\\", + }, + ), + Expression( + FStringExpressionElement { + range: 303..308, + expression: Name( + ExprName { + range: 304..307, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 308..309, + value: "\\", + }, + ), + Expression( + FStringExpressionElement { + range: 309..316, + expression: Name( + ExprName { + range: 310..313, + id: "bar", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 314..315, - value: "\\", - unicode: false, - implicit_concatenated: false, + elements: [ + Literal( + FStringLiteralElement { + range: 314..315, + value: "\\", + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -746,17 +873,23 @@ expression: parse_ast value: FString( ExprFString { range: 318..332, - values: [ - StringLiteral( - ExprStringLiteral { - range: 320..331, - value: "\\{foo\\}", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 318..332, + elements: [ + Literal( + FStringLiteralElement { + range: 320..331, + value: "\\{foo\\}", + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, @@ -767,41 +900,44 @@ expression: parse_ast value: FString( ExprFString { range: 333..373, - values: [ - FormattedValue( - ExprFormattedValue { - range: 337..370, - value: Name( - ExprName { - range: 343..346, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 347..369, - values: [ - StringLiteral( - ExprStringLiteral { + value: FStringValue { + inner: Single( + FString( + FString { + range: 333..373, + elements: [ + Expression( + FStringExpressionElement { + range: 337..370, + expression: Name( + ExprName { + range: 343..346, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 347..369, - value: "x\n y\n z\n", - unicode: false, - implicit_concatenated: false, + elements: [ + Literal( + FStringLiteralElement { + range: 347..369, + value: "x\n y\n z\n", + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings_with_unicode.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings_with_unicode.snap index 587845166d0c7..705c6e4d47155 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings_with_unicode.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings_with_unicode.snap @@ -9,40 +9,55 @@ expression: parse_ast value: FString( ExprFString { range: 0..29, - values: [ - StringLiteral( - ExprStringLiteral { - range: 2..5, - value: "foo", - unicode: true, - implicit_concatenated: true, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 9..14, - value: Name( - ExprName { - range: 10..13, - id: "bar", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 17..28, - value: "baz some", - unicode: false, - implicit_concatenated: true, - }, + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 0..6, + value: "foo", + unicode: true, + }, + ), + FString( + FString { + range: 7..15, + elements: [ + Expression( + FStringExpressionElement { + range: 9..14, + expression: Name( + ExprName { + range: 10..13, + id: "bar", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), + Literal( + StringLiteral { + range: 16..21, + value: "baz", + unicode: false, + }, + ), + Literal( + StringLiteral { + range: 22..29, + value: " some", + unicode: false, + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, @@ -53,40 +68,55 @@ expression: parse_ast value: FString( ExprFString { range: 30..59, - values: [ - StringLiteral( - ExprStringLiteral { - range: 31..34, - value: "foo", - unicode: false, - implicit_concatenated: true, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 38..43, - value: Name( - ExprName { - range: 39..42, - id: "bar", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 47..58, - value: "baz some", - unicode: true, - implicit_concatenated: true, - }, + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 30..35, + value: "foo", + unicode: false, + }, + ), + FString( + FString { + range: 36..44, + elements: [ + Expression( + FStringExpressionElement { + range: 38..43, + expression: Name( + ExprName { + range: 39..42, + id: "bar", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), + Literal( + StringLiteral { + range: 45..51, + value: "baz", + unicode: true, + }, + ), + Literal( + StringLiteral { + range: 52..59, + value: " some", + unicode: false, + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, @@ -97,40 +127,55 @@ expression: parse_ast value: FString( ExprFString { range: 60..89, - values: [ - StringLiteral( - ExprStringLiteral { - range: 61..64, - value: "foo", - unicode: false, - implicit_concatenated: true, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 68..73, - value: Name( - ExprName { - range: 69..72, - id: "bar", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 76..88, - value: "baz some", - unicode: false, - implicit_concatenated: true, - }, + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 60..65, + value: "foo", + unicode: false, + }, + ), + FString( + FString { + range: 66..74, + elements: [ + Expression( + FStringExpressionElement { + range: 68..73, + expression: Name( + ExprName { + range: 69..72, + id: "bar", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), + Literal( + StringLiteral { + range: 75..80, + value: "baz", + unicode: false, + }, + ), + Literal( + StringLiteral { + range: 81..89, + value: " some", + unicode: true, + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, @@ -141,40 +186,67 @@ expression: parse_ast value: FString( ExprFString { range: 90..128, - values: [ - StringLiteral( - ExprStringLiteral { - range: 92..103, - value: "foobar ", - unicode: true, - implicit_concatenated: true, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 103..108, - value: Name( - ExprName { - range: 104..107, - id: "baz", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 108..127, - value: " reallybarno", - unicode: false, - implicit_concatenated: true, - }, + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 90..96, + value: "foo", + unicode: true, + }, + ), + FString( + FString { + range: 97..116, + elements: [ + Literal( + FStringLiteralElement { + range: 99..103, + value: "bar ", + }, + ), + Expression( + FStringExpressionElement { + range: 103..108, + expression: Name( + ExprName { + range: 104..107, + id: "baz", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 108..115, + value: " really", + }, + ), + ], + }, + ), + Literal( + StringLiteral { + range: 117..123, + value: "bar", + unicode: true, + }, + ), + Literal( + StringLiteral { + range: 124..128, + value: "no", + unicode: false, + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__generator_expression_argument.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__generator_expression_argument.snap index 5d3cf3b2769a2..08f16c5d09f78 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__generator_expression_argument.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__generator_expression_argument.snap @@ -11,9 +11,15 @@ Call( value: StringLiteral( ExprStringLiteral { range: 0..3, - value: " ", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..3, + value: " ", + unicode: false, + }, + ), + }, }, ), attr: Identifier { @@ -66,9 +72,15 @@ Call( left: StringLiteral( ExprStringLiteral { range: 43..53, - value: "LIMIT %d", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 43..53, + value: "LIMIT %d", + unicode: false, + }, + ), + }, }, ), op: Mod, @@ -104,9 +116,15 @@ Call( left: StringLiteral( ExprStringLiteral { range: 91..102, - value: "OFFSET %d", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 91..102, + value: "OFFSET %d", + unicode: false, + }, + ), + }, }, ), op: Mod, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__match.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__match.snap index 79b81f92449e3..545c9396f93b0 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__match.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__match.snap @@ -14,9 +14,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 8..14, - value: "test", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 8..14, + value: "test", + unicode: false, + }, + ), + }, }, ), ), @@ -97,9 +103,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 81..88, - value: "label", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 81..88, + value: "label", + unicode: false, + }, + ), + }, }, ), ), @@ -108,9 +120,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 90..96, - value: "test", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 90..96, + value: "test", + unicode: false, + }, + ), + }, }, ), ], @@ -126,9 +144,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 118..125, - value: "label", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 118..125, + value: "label", + unicode: false, + }, + ), + }, }, ), ], diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parenthesized_with_statement.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parenthesized_with_statement.snap index 8707ba33d6e21..0e703191724d8 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parenthesized_with_statement.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parenthesized_with_statement.snap @@ -347,7 +347,7 @@ expression: "parse_suite(source, \"\").unwrap()" is_async: false, items: [ WithItem { - range: 184..195, + range: 183..196, context_expr: NamedExpr( ExprNamedExpr { range: 184..190, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_class.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_class.snap index ebf85a89e247b..28c1d74b4c8f9 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_class.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_class.snap @@ -116,9 +116,15 @@ expression: "parse_suite(source, \"\").unwrap()" StringLiteral( ExprStringLiteral { range: 80..89, - value: "default", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 80..89, + value: "default", + unicode: false, + }, + ), + }, }, ), ), diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_f_string.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_f_string.snap index 323e950616dd2..84364a344ec01 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_f_string.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_f_string.snap @@ -9,17 +9,23 @@ expression: parse_ast value: FString( ExprFString { range: 0..14, - values: [ - StringLiteral( - ExprStringLiteral { - range: 2..13, - value: "Hello world", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..14, + elements: [ + Literal( + FStringLiteralElement { + range: 2..13, + value: "Hello world", + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_kwargs.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_kwargs.snap index 5aeea6fccc478..1a66146c80fb2 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_kwargs.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_kwargs.snap @@ -22,9 +22,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 8..20, - value: "positional", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 8..20, + value: "positional", + unicode: false, + }, + ), + }, }, ), ], diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_print_2.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_print_2.snap index d72338562526b..63fe9f3c0a6fe 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_print_2.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_print_2.snap @@ -22,9 +22,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 6..19, - value: "Hello world", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 6..19, + value: "Hello world", + unicode: false, + }, + ), + }, }, ), NumberLiteral( diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_print_hello.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_print_hello.snap index 4e665b28312f9..351f287b92ba7 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_print_hello.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_print_hello.snap @@ -22,9 +22,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 6..19, - value: "Hello world", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 6..19, + value: "Hello world", + unicode: false, + }, + ), + }, }, ), ], diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_string.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_string.snap index 5f65e7d4a785c..8611f5f2fa6fe 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_string.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_string.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..13, - value: "Hello world", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..13, + value: "Hello world", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_type_declaration.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_type_declaration.snap index 24cd00399424f..7730469ff75ef 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_type_declaration.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__parse_type_declaration.snap @@ -81,9 +81,15 @@ expression: "parse_suite(source, \"\").unwrap()" right: StringLiteral( ExprStringLiteral { range: 48..61, - value: "ForwardRefY", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 48..61, + value: "ForwardRefY", + unicode: false, + }, + ), + }, }, ), }, @@ -843,4 +849,98 @@ expression: "parse_suite(source, \"\").unwrap()" ), }, ), + TypeAlias( + StmtTypeAlias { + range: 590..602, + name: Name( + ExprName { + range: 595..596, + id: "X", + ctx: Store, + }, + ), + type_params: None, + value: Name( + ExprName { + range: 599..602, + id: "int", + ctx: Load, + }, + ), + }, + ), + TypeAlias( + StmtTypeAlias { + range: 604..616, + name: Name( + ExprName { + range: 609..610, + id: "X", + ctx: Store, + }, + ), + type_params: None, + value: Name( + ExprName { + range: 613..616, + id: "str", + ctx: Load, + }, + ), + }, + ), + TypeAlias( + StmtTypeAlias { + range: 618..631, + name: Name( + ExprName { + range: 623..624, + id: "X", + ctx: Store, + }, + ), + type_params: None, + value: Name( + ExprName { + range: 627..631, + id: "type", + ctx: Load, + }, + ), + }, + ), + ClassDef( + StmtClassDef { + range: 632..653, + decorator_list: [], + name: Identifier { + id: "X", + range: 638..639, + }, + type_params: None, + arguments: None, + body: [ + TypeAlias( + StmtTypeAlias { + range: 641..653, + name: Name( + ExprName { + range: 646..647, + id: "X", + ctx: Store, + }, + ), + type_params: None, + value: Name( + ExprName { + range: 650..653, + id: "int", + ctx: Load, + }, + ), + }, + ), + ], + }, + ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__patma.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__patma.snap index ab1adbd35e711..c90e9f1e65a04 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__patma.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__patma.snap @@ -501,9 +501,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 484..489, - value: "seq", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 484..489, + value: "seq", + unicode: false, + }, + ), + }, }, ), ), @@ -530,9 +536,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 518..523, - value: "map", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 518..523, + value: "map", + unicode: false, + }, + ), + }, }, ), ), @@ -821,9 +833,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 664..667, - value: "X", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 664..667, + value: "X", + unicode: false, + }, + ), + }, }, ), }, @@ -1551,9 +1569,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 1287..1292, - value: "foo", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 1287..1292, + value: "foo", + unicode: false, + }, + ), + }, }, ), ], @@ -2469,9 +2493,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 2036..2038, - value: "", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 2036..2038, + value: "", + unicode: false, + }, + ), + }, }, ), }, @@ -2513,9 +2543,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 2064..2066, - value: "", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 2064..2066, + value: "", + unicode: false, + }, + ), + }, }, ), }, @@ -3131,9 +3167,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 2449..2452, - value: "X", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 2449..2452, + value: "X", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__try.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__try.snap index f653b8c7f0d8c..f2497947cac46 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__try.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__try.snap @@ -81,50 +81,56 @@ expression: parse_ast FString( ExprFString { range: 62..81, - values: [ - StringLiteral( - ExprStringLiteral { - range: 64..71, - value: "caught ", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 71..80, - value: Call( - ExprCall { - range: 72..79, - func: Name( - ExprName { - range: 72..76, - id: "type", - ctx: Load, + value: FStringValue { + inner: Single( + FString( + FString { + range: 62..81, + elements: [ + Literal( + FStringLiteralElement { + range: 64..71, + value: "caught ", }, ), - arguments: Arguments { - range: 76..79, - args: [ - Name( - ExprName { - range: 77..78, - id: "e", - ctx: Load, + Expression( + FStringExpressionElement { + range: 71..80, + expression: Call( + ExprCall { + range: 72..79, + func: Name( + ExprName { + range: 72..76, + id: "type", + ctx: Load, + }, + ), + arguments: Arguments { + range: 76..79, + args: [ + Name( + ExprName { + range: 77..78, + id: "e", + ctx: Load, + }, + ), + ], + keywords: [], + }, }, ), - ], - keywords: [], - }, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), ], @@ -175,50 +181,56 @@ expression: parse_ast FString( ExprFString { range: 114..133, - values: [ - StringLiteral( - ExprStringLiteral { - range: 116..123, - value: "caught ", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 123..132, - value: Call( - ExprCall { - range: 124..131, - func: Name( - ExprName { - range: 124..128, - id: "type", - ctx: Load, + value: FStringValue { + inner: Single( + FString( + FString { + range: 114..133, + elements: [ + Literal( + FStringLiteralElement { + range: 116..123, + value: "caught ", }, ), - arguments: Arguments { - range: 128..131, - args: [ - Name( - ExprName { - range: 129..130, - id: "e", - ctx: Load, + Expression( + FStringExpressionElement { + range: 123..132, + expression: Call( + ExprCall { + range: 124..131, + func: Name( + ExprName { + range: 124..128, + id: "type", + ctx: Load, + }, + ), + arguments: Arguments { + range: 128..131, + args: [ + Name( + ExprName { + range: 129..130, + id: "e", + ctx: Load, + }, + ), + ], + keywords: [], + }, }, ), - ], - keywords: [], - }, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), ], diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__try_star.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__try_star.snap index 2ed0abb3ea0fb..220516c86bffd 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__try_star.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__try_star.snap @@ -27,9 +27,15 @@ expression: parse_ast StringLiteral( ExprStringLiteral { range: 30..34, - value: "eg", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 30..34, + value: "eg", + unicode: false, + }, + ), + }, }, ), List( @@ -193,83 +199,87 @@ expression: parse_ast FString( ExprFString { range: 133..179, - values: [ - StringLiteral( - ExprStringLiteral { - range: 135..142, - value: "caught ", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 142..151, - value: Call( - ExprCall { - range: 143..150, - func: Name( - ExprName { - range: 143..147, - id: "type", - ctx: Load, + value: FStringValue { + inner: Single( + FString( + FString { + range: 133..179, + elements: [ + Literal( + FStringLiteralElement { + range: 135..142, + value: "caught ", + }, + ), + Expression( + FStringExpressionElement { + range: 142..151, + expression: Call( + ExprCall { + range: 143..150, + func: Name( + ExprName { + range: 143..147, + id: "type", + ctx: Load, + }, + ), + arguments: Arguments { + range: 147..150, + args: [ + Name( + ExprName { + range: 148..149, + id: "e", + ctx: Load, + }, + ), + ], + keywords: [], + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 151..164, + value: " with nested ", }, ), - arguments: Arguments { - range: 147..150, - args: [ - Name( - ExprName { - range: 148..149, - id: "e", + Expression( + FStringExpressionElement { + range: 164..178, + expression: Attribute( + ExprAttribute { + range: 165..177, + value: Name( + ExprName { + range: 165..166, + id: "e", + ctx: Load, + }, + ), + attr: Identifier { + id: "exceptions", + range: 167..177, + }, ctx: Load, }, ), - ], - keywords: [], - }, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 151..164, - value: " with nested ", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 164..178, - value: Attribute( - ExprAttribute { - range: 165..177, - value: Name( - ExprName { - range: 165..166, - id: "e", - ctx: Load, + debug_text: None, + conversion: None, + format_spec: None, }, ), - attr: Identifier { - id: "exceptions", - range: 167..177, - }, - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), ], @@ -320,83 +330,87 @@ expression: parse_ast FString( ExprFString { range: 213..259, - values: [ - StringLiteral( - ExprStringLiteral { - range: 215..222, - value: "caught ", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 222..231, - value: Call( - ExprCall { - range: 223..230, - func: Name( - ExprName { - range: 223..227, - id: "type", - ctx: Load, + value: FStringValue { + inner: Single( + FString( + FString { + range: 213..259, + elements: [ + Literal( + FStringLiteralElement { + range: 215..222, + value: "caught ", + }, + ), + Expression( + FStringExpressionElement { + range: 222..231, + expression: Call( + ExprCall { + range: 223..230, + func: Name( + ExprName { + range: 223..227, + id: "type", + ctx: Load, + }, + ), + arguments: Arguments { + range: 227..230, + args: [ + Name( + ExprName { + range: 228..229, + id: "e", + ctx: Load, + }, + ), + ], + keywords: [], + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, }, ), - arguments: Arguments { - range: 227..230, - args: [ - Name( - ExprName { - range: 228..229, - id: "e", + Literal( + FStringLiteralElement { + range: 231..244, + value: " with nested ", + }, + ), + Expression( + FStringExpressionElement { + range: 244..258, + expression: Attribute( + ExprAttribute { + range: 245..257, + value: Name( + ExprName { + range: 245..246, + id: "e", + ctx: Load, + }, + ), + attr: Identifier { + id: "exceptions", + range: 247..257, + }, ctx: Load, }, ), - ], - keywords: [], - }, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 231..244, - value: " with nested ", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 244..258, - value: Attribute( - ExprAttribute { - range: 245..257, - value: Name( - ExprName { - range: 245..246, - id: "e", - ctx: Load, + debug_text: None, + conversion: None, + format_spec: None, }, ), - attr: Identifier { - id: "exceptions", - range: 247..257, - }, - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), ], diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__type_as_identifier.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__type_as_identifier.snap index ad394b4042ac6..0296e7ad0511e 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__type_as_identifier.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__type_as_identifier.snap @@ -988,4 +988,44 @@ expression: "parse_suite(source, \"\").unwrap()" ), }, ), + Expr( + StmtExpr { + range: 652..666, + value: Lambda( + ExprLambda { + range: 652..666, + parameters: Some( + Parameters { + range: 659..660, + posonlyargs: [], + args: [ + ParameterWithDefault { + range: 659..660, + parameter: Parameter { + range: 659..660, + name: Identifier { + id: "x", + range: 659..660, + }, + annotation: None, + }, + default: None, + }, + ], + vararg: None, + kwonlyargs: [], + kwarg: None, + }, + ), + body: Name( + ExprName { + range: 662..666, + id: "type", + ctx: Load, + }, + ), + }, + ), + }, + ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__unicode_aliases.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__unicode_aliases.snap index ce30084c32dcd..7d811685fb945 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__unicode_aliases.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__unicode_aliases.snap @@ -18,9 +18,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 4..37, - value: "\u{8}another cool trick", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 4..37, + value: "\u{8}another cool trick", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__with_statement.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__with_statement.snap index de4e64d775aa1..dec15e10e878d 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__with_statement.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__with_statement.snap @@ -782,7 +782,7 @@ expression: "parse_suite(source, \"\").unwrap()" is_async: false, items: [ WithItem { - range: 382..393, + range: 381..394, context_expr: NamedExpr( ExprNamedExpr { range: 382..388, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__backspace_alias.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__backspace_alias.snap index f29c2f977121f..1e59128678e1a 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__backspace_alias.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__backspace_alias.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..15, - value: "\u{8}", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..15, + value: "\u{8}", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__bell_alias.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__bell_alias.snap index ef30240f8a89b..29d741f9b33b4 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__bell_alias.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__bell_alias.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..9, - value: "\u{7}", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..9, + value: "\u{7}", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__carriage_return_alias.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__carriage_return_alias.snap index 4224f30ab7cbe..594dcafd732e7 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__carriage_return_alias.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__carriage_return_alias.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..21, - value: "\r", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..21, + value: "\r", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__character_tabulation_with_justification_alias.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__character_tabulation_with_justification_alias.snap index 735816fc1fedd..8346f7b04585b 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__character_tabulation_with_justification_alias.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__character_tabulation_with_justification_alias.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..45, - value: "\u{89}", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..45, + value: "\u{89}", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__delete_alias.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__delete_alias.snap index e54a28743075d..7759077dd2cfb 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__delete_alias.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__delete_alias.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..12, - value: "\u{7f}", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..12, + value: "\u{7f}", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__dont_panic_on_8_in_octal_escape.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__dont_panic_on_8_in_octal_escape.snap index 8b8c0a4e68b5f..970c3626905e2 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__dont_panic_on_8_in_octal_escape.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__dont_panic_on_8_in_octal_escape.snap @@ -18,9 +18,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 7..16, - value: "\u{3}8[1m", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 7..16, + value: "\u{3}8[1m", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__double_quoted_byte.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__double_quoted_byte.snap index e3b24f2b52285..5a6129ecb14e5 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__double_quoted_byte.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__double_quoted_byte.snap @@ -9,265 +9,271 @@ expression: parse_ast value: BytesLiteral( ExprBytesLiteral { range: 0..738, - value: [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - 144, - 145, - 146, - 147, - 148, - 149, - 150, - 151, - 152, - 153, - 154, - 155, - 156, - 157, - 158, - 159, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 174, - 175, - 176, - 177, - 178, - 179, - 180, - 181, - 182, - 183, - 184, - 185, - 186, - 187, - 188, - 189, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 210, - 211, - 212, - 213, - 214, - 215, - 216, - 217, - 218, - 219, - 220, - 221, - 222, - 223, - 224, - 225, - 226, - 227, - 228, - 229, - 230, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 249, - 250, - 251, - 252, - 253, - 254, - 255, - ], - implicit_concatenated: false, + value: BytesLiteralValue { + inner: Single( + BytesLiteral { + range: 0..738, + value: [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + ], + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_alias.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_alias.snap index 871b5788cadb3..2efea4e2f0f9f 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_alias.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_alias.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..12, - value: "\u{1b}", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..12, + value: "\u{1b}", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_char_in_byte_literal.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_char_in_byte_literal.snap index 1ad9fb00a0f37..a62b6665c499f 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_char_in_byte_literal.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_char_in_byte_literal.snap @@ -9,19 +9,25 @@ expression: parse_ast value: BytesLiteral( ExprBytesLiteral { range: 0..13, - value: [ - 111, - 109, - 107, - 109, - 111, - 107, - 92, - 88, - 97, - 97, - ], - implicit_concatenated: false, + value: BytesLiteralValue { + inner: Single( + BytesLiteral { + range: 0..13, + value: [ + 111, + 109, + 107, + 109, + 111, + 107, + 92, + 88, + 97, + 97, + ], + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_octet.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_octet.snap index 1471b60aa0413..52c41dade1da0 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_octet.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__escape_octet.snap @@ -9,14 +9,20 @@ expression: parse_ast value: BytesLiteral( ExprBytesLiteral { range: 0..14, - value: [ - 35, - 97, - 4, - 83, - 52, - ], - implicit_concatenated: false, + value: BytesLiteralValue { + inner: Single( + BytesLiteral { + range: 0..14, + value: [ + 35, + 97, + 4, + 83, + 52, + ], + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__form_feed_alias.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__form_feed_alias.snap index d574d60f91466..652db948cbc28 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__form_feed_alias.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__form_feed_alias.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..15, - value: "\u{c}", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..15, + value: "\u{c}", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_constant_range.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_constant_range.snap index 2609db65ebcf0..ef91cbf428fdb 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_constant_range.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_constant_range.snap @@ -9,63 +9,65 @@ expression: parse_ast value: FString( ExprFString { range: 0..22, - values: [ - StringLiteral( - ExprStringLiteral { - range: 2..5, - value: "aaa", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..22, + elements: [ + Literal( + FStringLiteralElement { + range: 2..5, + value: "aaa", + }, + ), + Expression( + FStringExpressionElement { + range: 5..10, + expression: Name( + ExprName { + range: 6..9, + id: "bbb", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 10..13, + value: "ccc", + }, + ), + Expression( + FStringExpressionElement { + range: 13..18, + expression: Name( + ExprName { + range: 14..17, + id: "ddd", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 18..21, + value: "eee", + }, + ), + ], + }, + ), ), - FormattedValue( - ExprFormattedValue { - range: 5..10, - value: Name( - ExprName { - range: 6..9, - id: "bbb", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 10..13, - value: "ccc", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 13..18, - value: Name( - ExprName { - range: 14..17, - id: "ddd", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 18..21, - value: "eee", - unicode: false, - implicit_concatenated: false, - }, - ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_escaped_character.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_escaped_character.snap index 9d179474d18c1..8353b0e11c1d8 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_escaped_character.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_escaped_character.snap @@ -9,32 +9,38 @@ expression: parse_ast value: FString( ExprFString { range: 0..8, - values: [ - StringLiteral( - ExprStringLiteral { - range: 2..4, - value: "\\", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..8, + elements: [ + Literal( + FStringLiteralElement { + range: 2..4, + value: "\\", + }, + ), + Expression( + FStringExpressionElement { + range: 4..7, + expression: Name( + ExprName { + range: 5..6, + id: "x", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - FormattedValue( - ExprFormattedValue { - range: 4..7, - value: Name( - ExprName { - range: 5..6, - id: "x", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_escaped_newline.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_escaped_newline.snap index aa63b7d99d05c..5394a34336341 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_escaped_newline.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_escaped_newline.snap @@ -9,32 +9,38 @@ expression: parse_ast value: FString( ExprFString { range: 0..8, - values: [ - StringLiteral( - ExprStringLiteral { - range: 2..4, - value: "\n", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..8, + elements: [ + Literal( + FStringLiteralElement { + range: 2..4, + value: "\n", + }, + ), + Expression( + FStringExpressionElement { + range: 4..7, + expression: Name( + ExprName { + range: 5..6, + id: "x", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - FormattedValue( - ExprFormattedValue { - range: 4..7, - value: Name( - ExprName { - range: 5..6, - id: "x", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_line_continuation.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_line_continuation.snap index 52dd4c6e45842..10c759fefa07e 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_line_continuation.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_line_continuation.snap @@ -9,32 +9,38 @@ expression: parse_ast value: FString( ExprFString { range: 0..9, - values: [ - StringLiteral( - ExprStringLiteral { - range: 3..5, - value: "\\\n", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..9, + elements: [ + Literal( + FStringLiteralElement { + range: 3..5, + value: "\\\n", + }, + ), + Expression( + FStringExpressionElement { + range: 5..8, + expression: Name( + ExprName { + range: 6..7, + id: "x", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - FormattedValue( - ExprFormattedValue { - range: 5..8, - value: Name( - ExprName { - range: 6..7, - id: "x", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base.snap index 7927d57d4f621..f01086439af1a 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base.snap @@ -9,29 +9,37 @@ expression: parse_ast value: FString( ExprFString { range: 0..10, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..9, - value: Name( - ExprName { - range: 3..7, - id: "user", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..10, + elements: [ + Expression( + FStringExpressionElement { + range: 2..9, + expression: Name( + ExprName { + range: 3..7, + id: "user", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base_more.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base_more.snap index 1cf05d42dd09c..fe5c4f3497e08 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base_more.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base_more.snap @@ -9,65 +9,69 @@ expression: parse_ast value: FString( ExprFString { range: 0..38, - values: [ - StringLiteral( - ExprStringLiteral { - range: 2..6, - value: "mix ", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..38, + elements: [ + Literal( + FStringLiteralElement { + range: 2..6, + value: "mix ", + }, + ), + Expression( + FStringExpressionElement { + range: 6..13, + expression: Name( + ExprName { + range: 7..11, + id: "user", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 13..28, + value: " with text and ", + }, + ), + Expression( + FStringExpressionElement { + range: 28..37, + expression: Name( + ExprName { + range: 29..35, + id: "second", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - FormattedValue( - ExprFormattedValue { - range: 6..13, - value: Name( - ExprName { - range: 7..11, - id: "user", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 13..28, - value: " with text and ", - unicode: false, - implicit_concatenated: false, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 28..37, - value: Name( - ExprName { - range: 29..35, - id: "second", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: None, - }, - ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_format.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_format.snap index 5e17b1c8a2843..26d2fb22bef9a 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_format.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_format.snap @@ -9,46 +9,49 @@ expression: parse_ast value: FString( ExprFString { range: 0..14, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..13, - value: Name( - ExprName { - range: 3..7, - id: "user", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 9..12, - values: [ - StringLiteral( - ExprStringLiteral { + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..14, + elements: [ + Expression( + FStringExpressionElement { + range: 2..13, + expression: Name( + ExprName { + range: 3..7, + id: "user", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 9..12, - value: ">10", - unicode: false, - implicit_concatenated: false, + elements: [ + Literal( + FStringLiteralElement { + range: 9..12, + value: ">10", + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_unescaped_newline.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_unescaped_newline.snap index 7ec5e8b42a353..55797fae098c7 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_unescaped_newline.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_unescaped_newline.snap @@ -9,32 +9,38 @@ expression: parse_ast value: FString( ExprFString { range: 0..11, - values: [ - StringLiteral( - ExprStringLiteral { - range: 4..5, - value: "\n", - unicode: false, - implicit_concatenated: false, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..11, + elements: [ + Literal( + FStringLiteralElement { + range: 4..5, + value: "\n", + }, + ), + Expression( + FStringExpressionElement { + range: 5..8, + expression: Name( + ExprName { + range: 6..7, + id: "x", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - FormattedValue( - ExprFormattedValue { - range: 5..8, - value: Name( - ExprName { - range: 6..7, - id: "x", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__hts_alias.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__hts_alias.snap index 48eab469043b3..4120136451759 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__hts_alias.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__hts_alias.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..9, - value: "\u{88}", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..9, + value: "\u{88}", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_empty_fstring.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_empty_fstring.snap index 08b71212046b2..fccf2a0b9e18c 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_empty_fstring.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_empty_fstring.snap @@ -9,8 +9,16 @@ expression: "parse_suite(r#\"f\"\"\"#, \"\").unwrap()" value: FString( ExprFString { range: 0..3, - values: [], - implicit_concatenated: false, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..3, + elements: [], + }, + ), + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_1.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_1.snap index 97c70a7a22e64..3fa34cf133205 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_1.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_1.snap @@ -9,17 +9,32 @@ expression: parse_ast value: FString( ExprFString { range: 0..17, - values: [ - StringLiteral( - ExprStringLiteral { - range: 1..16, - value: "Hello world", - unicode: false, - implicit_concatenated: true, - }, + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 0..8, + value: "Hello ", + unicode: false, + }, + ), + FString( + FString { + range: 9..17, + elements: [ + Literal( + FStringLiteralElement { + range: 11..16, + value: "world", + }, + ), + ], + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_2.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_2.snap index 97c70a7a22e64..3fa34cf133205 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_2.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_2.snap @@ -9,17 +9,32 @@ expression: parse_ast value: FString( ExprFString { range: 0..17, - values: [ - StringLiteral( - ExprStringLiteral { - range: 1..16, - value: "Hello world", - unicode: false, - implicit_concatenated: true, - }, + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 0..8, + value: "Hello ", + unicode: false, + }, + ), + FString( + FString { + range: 9..17, + elements: [ + Literal( + FStringLiteralElement { + range: 11..16, + value: "world", + }, + ), + ], + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_3.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_3.snap index ccfe7c6484998..62c35e88a4483 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_3.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_3.snap @@ -9,33 +9,54 @@ expression: parse_ast value: FString( ExprFString { range: 0..22, - values: [ - StringLiteral( - ExprStringLiteral { - range: 1..16, - value: "Hello world", - unicode: false, - implicit_concatenated: true, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 16..21, - value: StringLiteral( - ExprStringLiteral { - range: 17..20, - value: "!", + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 0..8, + value: "Hello ", unicode: false, - implicit_concatenated: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, - }, + FString( + FString { + range: 9..22, + elements: [ + Literal( + FStringLiteralElement { + range: 11..16, + value: "world", + }, + ), + Expression( + FStringExpressionElement { + range: 16..21, + expression: StringLiteral( + ExprStringLiteral { + range: 17..20, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 17..20, + value: "!", + unicode: false, + }, + ), + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_4.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_4.snap index e6cb23a586837..05f12455f3dbb 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_4.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_f_string_concat_4.snap @@ -9,41 +9,61 @@ expression: parse_ast value: FString( ExprFString { range: 0..31, - values: [ - StringLiteral( - ExprStringLiteral { - range: 1..16, - value: "Hello world", - unicode: false, - implicit_concatenated: true, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 16..21, - value: StringLiteral( - ExprStringLiteral { - range: 17..20, - value: "!", + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 0..8, + value: "Hello ", unicode: false, - implicit_concatenated: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 24..30, - value: "again!", - unicode: false, - implicit_concatenated: true, - }, + FString( + FString { + range: 9..22, + elements: [ + Literal( + FStringLiteralElement { + range: 11..16, + value: "world", + }, + ), + Expression( + FStringExpressionElement { + range: 16..21, + expression: StringLiteral( + ExprStringLiteral { + range: 17..20, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 17..20, + value: "!", + unicode: false, + }, + ), + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), + Literal( + StringLiteral { + range: 23..31, + value: "again!", + unicode: false, + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring.snap index 6ee1be1ee840d..5b24ddca1728e 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring.snap @@ -9,47 +9,53 @@ expression: parse_ast value: FString( ExprFString { range: 0..18, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..5, - value: Name( - ExprName { - range: 3..4, - id: "a", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..18, + elements: [ + Expression( + FStringExpressionElement { + range: 2..5, + expression: Name( + ExprName { + range: 3..4, + id: "a", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Expression( + FStringExpressionElement { + range: 5..10, + expression: Name( + ExprName { + range: 7..8, + id: "b", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Literal( + FStringLiteralElement { + range: 10..17, + value: "{foo}", + }, + ), + ], + }, + ), ), - FormattedValue( - ExprFormattedValue { - range: 5..10, - value: Name( - ExprName { - range: 7..8, - id: "b", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - StringLiteral( - ExprStringLiteral { - range: 10..17, - value: "{foo}", - unicode: false, - implicit_concatenated: false, - }, - ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_equals.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_equals.snap index 25315bc0359a0..0972b502da856 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_equals.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_equals.snap @@ -9,43 +9,51 @@ expression: parse_ast value: FString( ExprFString { range: 0..13, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..12, - value: Compare( - ExprCompare { - range: 3..11, - left: NumberLiteral( - ExprNumberLiteral { - range: 3..5, - value: Int( - 42, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..13, + elements: [ + Expression( + FStringExpressionElement { + range: 2..12, + expression: Compare( + ExprCompare { + range: 3..11, + left: NumberLiteral( + ExprNumberLiteral { + range: 3..5, + value: Int( + 42, + ), + }, + ), + ops: [ + Eq, + ], + comparators: [ + NumberLiteral( + ExprNumberLiteral { + range: 9..11, + value: Int( + 42, + ), + }, + ), + ], + }, ), + debug_text: None, + conversion: None, + format_spec: None, }, ), - ops: [ - Eq, - ], - comparators: [ - NumberLiteral( - ExprNumberLiteral { - range: 9..11, - value: Int( - 42, - ), - }, - ), - ], - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_concatenation_string_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_concatenation_string_spec.snap index 070a1d0eea32f..fe1418fc69069 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_concatenation_string_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_concatenation_string_spec.snap @@ -9,49 +9,70 @@ expression: parse_ast value: FString( ExprFString { range: 0..16, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..15, - value: Name( - ExprName { - range: 3..6, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 7..14, - values: [ - FormattedValue( - ExprFormattedValue { + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..16, + elements: [ + Expression( + FStringExpressionElement { + range: 2..15, + expression: Name( + ExprName { + range: 3..6, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 7..14, - value: StringLiteral( - ExprStringLiteral { - range: 8..13, - value: "", - unicode: false, - implicit_concatenated: true, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, + elements: [ + Expression( + FStringExpressionElement { + range: 7..14, + expression: StringLiteral( + ExprStringLiteral { + range: 8..13, + value: StringLiteralValue { + inner: Concatenated( + ConcatenatedStringLiteral { + strings: [ + StringLiteral { + range: 8..10, + value: "", + unicode: false, + }, + StringLiteral { + range: 11..13, + value: "", + unicode: false, + }, + ], + value: "", + }, + ), + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_spec.snap index 39f80bde5c65c..d4e72897e0e04 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_spec.snap @@ -9,48 +9,53 @@ expression: parse_ast value: FString( ExprFString { range: 0..15, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..14, - value: Name( - ExprName { - range: 3..6, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 7..13, - values: [ - FormattedValue( - ExprFormattedValue { + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..15, + elements: [ + Expression( + FStringExpressionElement { + range: 2..14, + expression: Name( + ExprName { + range: 3..6, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 7..13, - value: Name( - ExprName { - range: 8..12, - id: "spec", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, + elements: [ + Expression( + FStringExpressionElement { + range: 7..13, + expression: Name( + ExprName { + range: 8..12, + id: "spec", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_string_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_string_spec.snap index 327506de08aa8..c00e35f945ff1 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_string_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_string_spec.snap @@ -9,49 +9,60 @@ expression: parse_ast value: FString( ExprFString { range: 0..13, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..12, - value: Name( - ExprName { - range: 3..6, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 7..11, - values: [ - FormattedValue( - ExprFormattedValue { + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..13, + elements: [ + Expression( + FStringExpressionElement { + range: 2..12, + expression: Name( + ExprName { + range: 3..6, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 7..11, - value: StringLiteral( - ExprStringLiteral { - range: 8..10, - value: "", - unicode: false, - implicit_concatenated: false, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, + elements: [ + Expression( + FStringExpressionElement { + range: 7..11, + expression: StringLiteral( + ExprStringLiteral { + range: 8..10, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 8..10, + value: "", + unicode: false, + }, + ), + }, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_equals.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_equals.snap index 216021cec10c5..b1284e5cca29c 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_equals.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_equals.snap @@ -9,43 +9,51 @@ expression: parse_ast value: FString( ExprFString { range: 0..11, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..10, - value: Compare( - ExprCompare { - range: 3..9, - left: NumberLiteral( - ExprNumberLiteral { - range: 3..4, - value: Int( - 1, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..11, + elements: [ + Expression( + FStringExpressionElement { + range: 2..10, + expression: Compare( + ExprCompare { + range: 3..9, + left: NumberLiteral( + ExprNumberLiteral { + range: 3..4, + value: Int( + 1, + ), + }, + ), + ops: [ + NotEq, + ], + comparators: [ + NumberLiteral( + ExprNumberLiteral { + range: 8..9, + value: Int( + 2, + ), + }, + ), + ], + }, ), + debug_text: None, + conversion: None, + format_spec: None, }, ), - ops: [ - NotEq, - ], - comparators: [ - NumberLiteral( - ExprNumberLiteral { - range: 8..9, - value: Int( - 2, - ), - }, - ), - ], - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_nested_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_nested_spec.snap index cb1664e20c9c2..ba4061fddeee7 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_nested_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_nested_spec.snap @@ -9,41 +9,44 @@ expression: parse_ast value: FString( ExprFString { range: 0..13, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..12, - value: Name( - ExprName { - range: 3..6, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 7..11, - values: [ - StringLiteral( - ExprStringLiteral { + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..13, + elements: [ + Expression( + FStringExpressionElement { + range: 2..12, + expression: Name( + ExprName { + range: 3..6, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FStringFormatSpec { range: 7..11, - value: "spec", - unicode: false, - implicit_concatenated: false, + elements: [ + Literal( + FStringLiteralElement { + range: 7..11, + value: "spec", + }, + ), + ], }, ), - ], - implicit_concatenated: false, - }, - ), - ), - }, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_prec_space.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_prec_space.snap index 134e8043877e3..7c3ec7583dd4e 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_prec_space.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_prec_space.snap @@ -9,29 +9,37 @@ expression: parse_ast value: FString( ExprFString { range: 0..10, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..9, - value: Name( - ExprName { - range: 3..4, - id: "x", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: " =", - }, - ), - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..10, + elements: [ + Expression( + FStringExpressionElement { + range: 2..9, + expression: Name( + ExprName { + range: 3..4, + id: "x", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: " =", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_trailing_space.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_trailing_space.snap index b7c6e8505810c..47b37caa7f340 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_trailing_space.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_trailing_space.snap @@ -9,29 +9,37 @@ expression: parse_ast value: FString( ExprFString { range: 0..10, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..9, - value: Name( - ExprName { - range: 3..4, - id: "x", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "= ", - }, - ), - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..10, + elements: [ + Expression( + FStringExpressionElement { + range: 2..9, + expression: Name( + ExprName { + range: 3..4, + id: "x", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "= ", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_yield_expr.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_yield_expr.snap index 32693e49d7ac4..39219b2044779 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_yield_expr.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_yield_expr.snap @@ -9,23 +9,31 @@ expression: parse_ast value: FString( ExprFString { range: 0..10, - values: [ - FormattedValue( - ExprFormattedValue { - range: 2..9, - value: Yield( - ExprYield { - range: 3..8, - value: None, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..10, + elements: [ + Expression( + FStringExpressionElement { + range: 2..9, + expression: Yield( + ExprYield { + range: 3..8, + value: None, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_string_concat.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_string_concat.snap index 93c14088eb2f0..df7acef064365 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_string_concat.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_string_concat.snap @@ -9,9 +9,25 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..16, - value: "Hello world", - unicode: false, - implicit_concatenated: true, + value: StringLiteralValue { + inner: Concatenated( + ConcatenatedStringLiteral { + strings: [ + StringLiteral { + range: 0..8, + value: "Hello ", + unicode: false, + }, + StringLiteral { + range: 9..16, + value: "world", + unicode: false, + }, + ], + value: "Hello world", + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_string_triple_quotes_with_kind.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_string_triple_quotes_with_kind.snap index 9347faf323fa9..071761efae957 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_string_triple_quotes_with_kind.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_string_triple_quotes_with_kind.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..20, - value: "Hello, world!", - unicode: true, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..20, + value: "Hello, world!", + unicode: true, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_f_string_concat_1.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_f_string_concat_1.snap index df260efb74a14..f28bda3133050 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_f_string_concat_1.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_f_string_concat_1.snap @@ -9,17 +9,32 @@ expression: parse_ast value: FString( ExprFString { range: 0..18, - values: [ - StringLiteral( - ExprStringLiteral { - range: 2..17, - value: "Hello world", - unicode: true, - implicit_concatenated: true, - }, + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 0..9, + value: "Hello ", + unicode: true, + }, + ), + FString( + FString { + range: 10..18, + elements: [ + Literal( + FStringLiteralElement { + range: 12..17, + value: "world", + }, + ), + ], + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_f_string_concat_2.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_f_string_concat_2.snap index aced9ed7983cd..dc6afd4e42494 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_f_string_concat_2.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_f_string_concat_2.snap @@ -9,17 +9,39 @@ expression: parse_ast value: FString( ExprFString { range: 0..22, - values: [ - StringLiteral( - ExprStringLiteral { - range: 2..21, - value: "Hello world!", - unicode: true, - implicit_concatenated: true, - }, + value: FStringValue { + inner: Concatenated( + [ + Literal( + StringLiteral { + range: 0..9, + value: "Hello ", + unicode: true, + }, + ), + FString( + FString { + range: 10..18, + elements: [ + Literal( + FStringLiteralElement { + range: 12..17, + value: "world", + }, + ), + ], + }, + ), + Literal( + StringLiteral { + range: 19..22, + value: "!", + unicode: false, + }, + ), + ], ), - ], - implicit_concatenated: true, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_string_concat_1.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_string_concat_1.snap index 21dd4a1c10911..601474e802474 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_string_concat_1.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_string_concat_1.snap @@ -9,9 +9,25 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..17, - value: "Hello world", - unicode: false, - implicit_concatenated: true, + value: StringLiteralValue { + inner: Concatenated( + ConcatenatedStringLiteral { + strings: [ + StringLiteral { + range: 0..8, + value: "Hello ", + unicode: false, + }, + StringLiteral { + range: 9..17, + value: "world", + unicode: true, + }, + ], + value: "Hello world", + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_string_concat_2.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_string_concat_2.snap index 19c9f87309d02..5a84316d8a220 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_string_concat_2.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_u_string_concat_2.snap @@ -9,9 +9,25 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..17, - value: "Hello world", - unicode: true, - implicit_concatenated: true, + value: StringLiteralValue { + inner: Concatenated( + ConcatenatedStringLiteral { + strings: [ + StringLiteral { + range: 0..9, + value: "Hello ", + unicode: true, + }, + StringLiteral { + range: 10..17, + value: "world", + unicode: false, + }, + ], + value: "Hello world", + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_byte_literal_1.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_byte_literal_1.snap index 0ddea1aeca5ff..d8d18c4fe34de 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_byte_literal_1.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_byte_literal_1.snap @@ -9,13 +9,19 @@ expression: parse_ast value: BytesLiteral( ExprBytesLiteral { range: 0..8, - value: [ - 92, - 120, - 49, - 122, - ], - implicit_concatenated: false, + value: BytesLiteralValue { + inner: Single( + BytesLiteral { + range: 0..8, + value: [ + 92, + 120, + 49, + 122, + ], + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_byte_literal_2.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_byte_literal_2.snap index c7f13431590a8..ec5562eb0b002 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_byte_literal_2.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_byte_literal_2.snap @@ -9,11 +9,17 @@ expression: parse_ast value: BytesLiteral( ExprBytesLiteral { range: 0..6, - value: [ - 92, - 92, - ], - implicit_concatenated: false, + value: BytesLiteralValue { + inner: Single( + BytesLiteral { + range: 0..6, + value: [ + 92, + 92, + ], + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_fstring.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_fstring.snap index 65f4daf83d8d7..05fe49bbf73ad 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_fstring.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__raw_fstring.snap @@ -9,24 +9,32 @@ expression: parse_ast value: FString( ExprFString { range: 0..7, - values: [ - FormattedValue( - ExprFormattedValue { - range: 3..6, - value: Name( - ExprName { - range: 4..5, - id: "x", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..7, + elements: [ + Expression( + FStringExpressionElement { + range: 3..6, + expression: Name( + ExprName { + range: 4..5, + id: "x", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__single_quoted_byte.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__single_quoted_byte.snap index e3b24f2b52285..5a6129ecb14e5 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__single_quoted_byte.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__single_quoted_byte.snap @@ -9,265 +9,271 @@ expression: parse_ast value: BytesLiteral( ExprBytesLiteral { range: 0..738, - value: [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - 144, - 145, - 146, - 147, - 148, - 149, - 150, - 151, - 152, - 153, - 154, - 155, - 156, - 157, - 158, - 159, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 174, - 175, - 176, - 177, - 178, - 179, - 180, - 181, - 182, - 183, - 184, - 185, - 186, - 187, - 188, - 189, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 210, - 211, - 212, - 213, - 214, - 215, - 216, - 217, - 218, - 219, - 220, - 221, - 222, - 223, - 224, - 225, - 226, - 227, - 228, - 229, - 230, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 249, - 250, - 251, - 252, - 253, - 254, - 255, - ], - implicit_concatenated: false, + value: BytesLiteralValue { + inner: Single( + BytesLiteral { + range: 0..738, + value: [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + ], + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_mac_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_mac_eol.snap index 50d87b93a57cc..a20e906204e44 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_mac_eol.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_mac_eol.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..18, - value: "text more text", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..18, + value: "text more text", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_unix_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_unix_eol.snap index 50d87b93a57cc..a20e906204e44 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_unix_eol.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_unix_eol.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..18, - value: "text more text", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..18, + value: "text more text", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_windows_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_windows_eol.snap index fcee590ad5ca8..29f69a54bc297 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_windows_eol.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_windows_eol.snap @@ -9,9 +9,15 @@ expression: parse_ast value: StringLiteral( ExprStringLiteral { range: 0..19, - value: "text more text", - unicode: false, - implicit_concatenated: false, + value: StringLiteralValue { + inner: Single( + StringLiteral { + range: 0..19, + value: "text more text", + unicode: false, + }, + ), + }, }, ), }, diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__triple_quoted_raw_fstring.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__triple_quoted_raw_fstring.snap index 6793e65f73804..c772d6a052128 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__triple_quoted_raw_fstring.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__triple_quoted_raw_fstring.snap @@ -9,24 +9,32 @@ expression: parse_ast value: FString( ExprFString { range: 0..11, - values: [ - FormattedValue( - ExprFormattedValue { - range: 5..8, - value: Name( - ExprName { - range: 6..7, - id: "x", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, + value: FStringValue { + inner: Single( + FString( + FString { + range: 0..11, + elements: [ + Expression( + FStringExpressionElement { + range: 5..8, + expression: Name( + ExprName { + range: 6..7, + id: "x", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + }, + ), ), - ], - implicit_concatenated: false, + }, }, ), }, diff --git a/crates/ruff_python_parser/src/soft_keywords.rs b/crates/ruff_python_parser/src/soft_keywords.rs index f7aab9c1137a6..379ae1c08db38 100644 --- a/crates/ruff_python_parser/src/soft_keywords.rs +++ b/crates/ruff_python_parser/src/soft_keywords.rs @@ -1,6 +1,7 @@ -use crate::{lexer::LexResult, token::Tok, Mode}; use itertools::{Itertools, MultiPeek}; +use crate::{lexer::LexResult, token::Tok, Mode}; + /// An [`Iterator`] that transforms a token stream to accommodate soft keywords (namely, `match` /// `case`, and `type`). /// @@ -21,7 +22,7 @@ where I: Iterator, { underlying: MultiPeek, - start_of_line: bool, + position: Position, } impl SoftKeywordTransformer @@ -31,7 +32,11 @@ where pub fn new(lexer: I, mode: Mode) -> Self { Self { underlying: lexer.multipeek(), // spell-checker:ignore multipeek - start_of_line: matches!(mode, Mode::Module), + position: if mode == Mode::Expression { + Position::Other + } else { + Position::Statement + }, } } } @@ -49,7 +54,6 @@ where // If the token is a soft keyword e.g. `type`, `match`, or `case`, check if it's // used as an identifier. We assume every soft keyword use is an identifier unless // a heuristic is met. - match tok { // For `match` and `case`, all of the following conditions must be met: // 1. The token is at the start of a logical line. @@ -57,9 +61,9 @@ where // inside a parenthesized expression, list, or dictionary). // 3. The top-level colon is not the immediate sibling of a `match` or `case` token. // (This is to avoid treating `match` or `case` as identifiers when annotated with - // type hints.) type hints.) + // type hints.) Tok::Match | Tok::Case => { - if self.start_of_line { + if matches!(self.position, Position::Statement) { let mut nesting = 0; let mut first = true; let mut seen_colon = false; @@ -93,7 +97,10 @@ where // 2. The type token is immediately followed by a name token. // 3. The name token is eventually followed by an equality token. Tok::Type => { - if self.start_of_line { + if matches!( + self.position, + Position::Statement | Position::SimpleStatement + ) { let mut is_type_alias = false; if let Some(Ok((tok, _))) = self.underlying.peek() { if matches!( @@ -132,18 +139,56 @@ where } } - self.start_of_line = next.as_ref().is_some_and(|lex_result| { - lex_result.as_ref().is_ok_and(|(tok, _)| { - if matches!(tok, Tok::NonLogicalNewline | Tok::Comment { .. }) { - return self.start_of_line; + // Update the position, to track whether we're at the start of a logical line. + if let Some(lex_result) = next.as_ref() { + if let Ok((tok, _)) = lex_result.as_ref() { + match tok { + Tok::NonLogicalNewline | Tok::Comment { .. } => { + // Nothing to do. + } + Tok::StartModule | Tok::Newline | Tok::Indent | Tok::Dedent => { + self.position = Position::Statement; + } + // If we see a semicolon, assume we're at the start of a simple statement, as in: + // ```python + // type X = int; type Y = float + // ``` + Tok::Semi => { + self.position = Position::SimpleStatement; + } + // If we see a colon, and we're not in a nested context, assume we're at the + // start of a simple statement, as in: + // ```python + // class Class: type X = int + // ``` + Tok::Colon if self.position == Position::Other => { + self.position = Position::SimpleStatement; + } + Tok::Lpar | Tok::Lsqb | Tok::Lbrace => { + self.position = if let Position::Nested(depth) = self.position { + Position::Nested(depth.saturating_add(1)) + } else { + Position::Nested(1) + }; + } + Tok::Rpar | Tok::Rsqb | Tok::Rbrace => { + self.position = if let Position::Nested(depth) = self.position { + let depth = depth.saturating_sub(1); + if depth > 0 { + Position::Nested(depth) + } else { + Position::Other + } + } else { + Position::Other + }; + } + _ => { + self.position = Position::Other; + } } - - matches!( - tok, - Tok::StartModule | Tok::Newline | Tok::Indent | Tok::Dedent - ) - }) - }); + } + } next } @@ -161,3 +206,19 @@ fn soft_to_name(tok: &Tok) -> Tok { name: name.to_owned(), } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Position { + /// The lexer is at the start of a logical line, i.e., the start of a simple or compound statement. + Statement, + /// The lexer is at the start of a simple statement, e.g., a statement following a semicolon + /// or colon, as in: + /// ```python + /// class Class: type X = int + /// ``` + SimpleStatement, + /// The lexer is within brackets, with the given bracket nesting depth. + Nested(u32), + /// The lexer is some other location. + Other, +} diff --git a/crates/ruff_python_parser/src/string.rs b/crates/ruff_python_parser/src/string.rs index a3fa6f6495467..ab9106ff31a25 100644 --- a/crates/ruff_python_parser/src/string.rs +++ b/crates/ruff_python_parser/src/string.rs @@ -7,9 +7,9 @@ use crate::lexer::{LexicalError, LexicalErrorType}; use crate::token::{StringKind, Tok}; pub(crate) enum StringType { - Str(ast::ExprStringLiteral), - Bytes(ast::ExprBytesLiteral), - FString(ast::ExprFString), + Str(ast::StringLiteral), + Bytes(ast::BytesLiteral), + FString(ast::FString), } impl Ranged for StringType { @@ -22,11 +22,12 @@ impl Ranged for StringType { } } -impl StringType { - fn is_unicode(&self) -> bool { - match self { - Self::Str(ast::ExprStringLiteral { unicode, .. }) => *unicode, - _ => false, +impl From for Expr { + fn from(string: StringType) -> Self { + match string { + StringType::Str(node) => Expr::from(node), + StringType::Bytes(node) => Expr::from(node), + StringType::FString(node) => Expr::from(node), } } } @@ -35,14 +36,16 @@ struct StringParser<'a> { rest: &'a str, kind: StringKind, location: TextSize, + range: TextRange, } impl<'a> StringParser<'a> { - fn new(source: &'a str, kind: StringKind, start: TextSize) -> Self { + fn new(source: &'a str, kind: StringKind, start: TextSize, range: TextRange) -> Self { Self { rest: source, kind, location: start, + range, } } @@ -59,11 +62,6 @@ impl<'a> StringParser<'a> { self.location } - #[inline] - fn range(&self, start_location: TextSize) -> TextRange { - TextRange::new(start_location, self.location) - } - /// Returns the next byte in the string, if there is one. /// /// # Panics @@ -122,10 +120,8 @@ impl<'a> StringParser<'a> { len += 1; } - // SAFETY: radix_bytes is always going to be in the ASCII range. - #[allow(unsafe_code)] - let radix_str = unsafe { std::str::from_utf8_unchecked(&radix_bytes[..len]) }; - + // OK because radix_bytes is always going to be in the ASCII range. + let radix_str = std::str::from_utf8(&radix_bytes[..len]).expect("ASCII bytes"); let value = u32::from_str_radix(radix_str, 8).unwrap(); char::from_u32(value).unwrap() } @@ -206,9 +202,8 @@ impl<'a> StringParser<'a> { Ok(()) } - fn parse_fstring_middle(&mut self) -> Result { + fn parse_fstring_middle(&mut self) -> Result { let mut value = String::new(); - let start_location = self.get_pos(); while let Some(ch) = self.next_char() { match ch { // We can encounter a `\` as the last character in a `FStringMiddle` @@ -244,17 +239,14 @@ impl<'a> StringParser<'a> { ch => value.push(ch), } } - Ok(Expr::from(ast::ExprStringLiteral { + Ok(ast::FStringElement::Literal(ast::FStringLiteralElement { value, - unicode: false, - implicit_concatenated: false, - range: self.range(start_location), + range: self.range, })) } fn parse_bytes(&mut self) -> Result { let mut content = String::new(); - let start_location = self.get_pos(); while let Some(ch) = self.next_char() { match ch { '\\' if !self.kind.is_raw() => { @@ -274,15 +266,13 @@ impl<'a> StringParser<'a> { } } - Ok(StringType::Bytes(ast::ExprBytesLiteral { + Ok(StringType::Bytes(ast::BytesLiteral { value: content.chars().map(|c| c as u8).collect::>(), - implicit_concatenated: false, - range: self.range(start_location), + range: self.range, })) } fn parse_string(&mut self) -> Result { - let start_location = self.get_pos(); let mut value = String::new(); if self.kind.is_raw() { @@ -301,11 +291,10 @@ impl<'a> StringParser<'a> { self.parse_escaped_char(&mut value)?; } } - Ok(StringType::Str(ast::ExprStringLiteral { + Ok(StringType::Str(ast::StringLiteral { value, unicode: self.kind.is_unicode(), - implicit_concatenated: false, - range: self.range(start_location), + range: self.range, })) } @@ -322,38 +311,37 @@ pub(crate) fn parse_string_literal( source: &str, kind: StringKind, triple_quoted: bool, - start_location: TextSize, + range: TextRange, ) -> Result { - let start_location = start_location + let start_location = range.start() + kind.prefix_len() + if triple_quoted { TextSize::from(3) } else { TextSize::from(1) }; - StringParser::new(source, kind, start_location).parse() + StringParser::new(source, kind, start_location, range).parse() } -pub(crate) fn parse_fstring_middle( +pub(crate) fn parse_fstring_literal_element( source: &str, is_raw: bool, - start_location: TextSize, -) -> Result { + range: TextRange, +) -> Result { let kind = if is_raw { StringKind::RawString } else { StringKind::String }; - StringParser::new(source, kind, start_location).parse_fstring_middle() + StringParser::new(source, kind, range.start(), range).parse_fstring_middle() } -/// Concatenate a list of string literals into a single string expression. -pub(crate) fn concatenate_strings( +pub(crate) fn concatenated_strings( strings: Vec, range: TextRange, ) -> Result { #[cfg(debug_assertions)] - debug_assert!(!strings.is_empty()); + debug_assert!(strings.len() > 1); let mut has_fstring = false; let mut byte_literal_count = 0; @@ -365,7 +353,6 @@ pub(crate) fn concatenate_strings( } } let has_bytes = byte_literal_count > 0; - let implicit_concatenated = strings.len() > 1; if has_bytes && byte_literal_count < strings.len() { return Err(LexicalError { @@ -377,111 +364,44 @@ pub(crate) fn concatenate_strings( } if has_bytes { - let mut content: Vec = vec![]; + let mut values = Vec::with_capacity(strings.len()); for string in strings { match string { - StringType::Bytes(ast::ExprBytesLiteral { value, .. }) => content.extend(value), + StringType::Bytes(value) => values.push(value), _ => unreachable!("Unexpected non-bytes literal."), } } - return Ok(ast::ExprBytesLiteral { - value: content, - implicit_concatenated, + return Ok(Expr::from(ast::ExprBytesLiteral { + value: ast::BytesLiteralValue::concatenated(values), range, - } - .into()); + })); } if !has_fstring { - let mut content = String::new(); - let is_unicode = strings.first().map_or(false, StringType::is_unicode); + let mut values = Vec::with_capacity(strings.len()); for string in strings { match string { - StringType::Str(ast::ExprStringLiteral { value, .. }) => content.push_str(&value), + StringType::Str(value) => values.push(value), _ => unreachable!("Unexpected non-string literal."), } } - return Ok(ast::ExprStringLiteral { - value: content, - unicode: is_unicode, - implicit_concatenated, + return Ok(Expr::from(ast::ExprStringLiteral { + value: ast::StringLiteralValue::concatenated(values), range, - } - .into()); - } - - // De-duplicate adjacent constants. - let mut deduped: Vec = vec![]; - let mut current = String::new(); - let mut current_start = range.start(); - let mut current_end = range.end(); - let mut is_unicode = false; - - let take_current = |current: &mut String, start, end, unicode| -> Expr { - Expr::StringLiteral(ast::ExprStringLiteral { - value: std::mem::take(current), - unicode, - implicit_concatenated, - range: TextRange::new(start, end), - }) - }; + })); + } + let mut parts = Vec::with_capacity(strings.len()); for string in strings { - let string_range = string.range(); match string { - StringType::FString(ast::ExprFString { values, .. }) => { - for value in values { - let value_range = value.range(); - match value { - Expr::FormattedValue { .. } => { - if !current.is_empty() { - deduped.push(take_current( - &mut current, - current_start, - current_end, - is_unicode, - )); - } - deduped.push(value); - is_unicode = false; - } - Expr::StringLiteral(ast::ExprStringLiteral { value, unicode, .. }) => { - if current.is_empty() { - is_unicode |= unicode; - current_start = value_range.start(); - } - current_end = value_range.end(); - current.push_str(&value); - } - _ => { - unreachable!("Expected `Expr::FormattedValue` or `Expr::StringLiteral`") - } - } - } - } - StringType::Str(ast::ExprStringLiteral { value, unicode, .. }) => { - if current.is_empty() { - is_unicode |= unicode; - current_start = string_range.start(); - } - current_end = string_range.end(); - current.push_str(&value); - } + StringType::FString(fstring) => parts.push(ast::FStringPart::FString(fstring)), + StringType::Str(string) => parts.push(ast::FStringPart::Literal(string)), StringType::Bytes(_) => unreachable!("Unexpected bytes literal."), } } - if !current.is_empty() { - deduped.push(take_current( - &mut current, - current_start, - current_end, - is_unicode, - )); - } Ok(ast::ExprFString { - values: deduped, - implicit_concatenated, + value: ast::FStringValue::concatenated(parts), range, } .into()) diff --git a/crates/ruff_python_semantic/src/analyze/class.rs b/crates/ruff_python_semantic/src/analyze/class.rs new file mode 100644 index 0000000000000..3efc01ff33754 --- /dev/null +++ b/crates/ruff_python_semantic/src/analyze/class.rs @@ -0,0 +1,57 @@ +use rustc_hash::FxHashSet; + +use ruff_python_ast as ast; +use ruff_python_ast::call_path::CallPath; +use ruff_python_ast::helpers::map_subscript; + +use crate::{BindingId, SemanticModel}; + +/// Return `true` if any base class of a class definition matches a predicate. +pub fn any_over_body( + class_def: &ast::StmtClassDef, + semantic: &SemanticModel, + func: &dyn Fn(CallPath) -> bool, +) -> bool { + fn inner( + class_def: &ast::StmtClassDef, + semantic: &SemanticModel, + func: &dyn Fn(CallPath) -> bool, + seen: &mut FxHashSet, + ) -> bool { + class_def.bases().iter().any(|expr| { + // If the base class itself matches the pattern, then this does too. + // Ex) `class Foo(BaseModel): ...` + if semantic + .resolve_call_path(map_subscript(expr)) + .is_some_and(func) + { + return true; + } + + // If the base class extends a class that matches the pattern, then this does too. + // Ex) `class Bar(BaseModel): ...; class Foo(Bar): ...` + if let Some(id) = semantic.lookup_attribute(map_subscript(expr)) { + if seen.insert(id) { + let binding = semantic.binding(id); + if let Some(base_class) = binding + .kind + .as_class_definition() + .map(|id| &semantic.scopes[*id]) + .and_then(|scope| scope.kind.as_class()) + { + if inner(base_class, semantic, func, seen) { + return true; + } + } + } + } + false + }) + } + + if class_def.bases().is_empty() { + return false; + } + + inner(class_def, semantic, func, &mut FxHashSet::default()) +} diff --git a/crates/ruff_python_semantic/src/analyze/imports.rs b/crates/ruff_python_semantic/src/analyze/imports.rs new file mode 100644 index 0000000000000..a4a9ddc134486 --- /dev/null +++ b/crates/ruff_python_semantic/src/analyze/imports.rs @@ -0,0 +1,55 @@ +use ruff_python_ast::{self as ast, Expr, Stmt}; + +use crate::SemanticModel; + +/// Returns `true` if a [`Stmt`] is a `sys.path` modification, as in: +/// ```python +/// import sys +/// +/// sys.path.append("../") +/// ``` +pub fn is_sys_path_modification(stmt: &Stmt, semantic: &SemanticModel) -> bool { + let Stmt::Expr(ast::StmtExpr { value, range: _ }) = stmt else { + return false; + }; + let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else { + return false; + }; + semantic + .resolve_call_path(func.as_ref()) + .is_some_and(|call_path| { + matches!( + call_path.as_slice(), + [ + "sys", + "path", + "append" + | "insert" + | "extend" + | "remove" + | "pop" + | "clear" + | "reverse" + | "sort" + ] + ) + }) +} + +/// Returns `true` if a [`Stmt`] is a `matplotlib.use` activation, as in: +/// ```python +/// import matplotlib +/// +/// matplotlib.use("Agg") +/// ``` +pub fn is_matplotlib_activation(stmt: &Stmt, semantic: &SemanticModel) -> bool { + let Stmt::Expr(ast::StmtExpr { value, range: _ }) = stmt else { + return false; + }; + let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else { + return false; + }; + semantic + .resolve_call_path(func.as_ref()) + .is_some_and(|call_path| matches!(call_path.as_slice(), ["matplotlib", "use"])) +} diff --git a/crates/ruff_python_semantic/src/analyze/mod.rs b/crates/ruff_python_semantic/src/analyze/mod.rs index 941309a526c26..0376f63c39f43 100644 --- a/crates/ruff_python_semantic/src/analyze/mod.rs +++ b/crates/ruff_python_semantic/src/analyze/mod.rs @@ -1,4 +1,6 @@ +pub mod class; pub mod function_type; +pub mod imports; pub mod logging; pub mod type_inference; pub mod typing; diff --git a/crates/ruff_python_semantic/src/analyze/type_inference.rs b/crates/ruff_python_semantic/src/analyze/type_inference.rs index f5261cd683664..427bdddca3e22 100644 --- a/crates/ruff_python_semantic/src/analyze/type_inference.rs +++ b/crates/ruff_python_semantic/src/analyze/type_inference.rs @@ -323,7 +323,6 @@ impl From<&Expr> for ResolvedPythonType { | Expr::YieldFrom(_) | Expr::Compare(_) | Expr::Call(_) - | Expr::FormattedValue(_) | Expr::Attribute(_) | Expr::Subscript(_) | Expr::Starred(_) diff --git a/crates/ruff_python_semantic/src/analyze/typing.rs b/crates/ruff_python_semantic/src/analyze/typing.rs index bd18f70ba8aae..2dd7f1003e398 100644 --- a/crates/ruff_python_semantic/src/analyze/typing.rs +++ b/crates/ruff_python_semantic/src/analyze/typing.rs @@ -568,3 +568,126 @@ pub fn resolve_assignment<'a>( _ => None, } } + +/// Find the assigned [`Expr`] for a given symbol, if any. +/// +/// For example given: +/// ```python +/// foo = 42 +/// (bar, bla) = 1, "str" +/// ``` +/// +/// This function will return a `NumberLiteral` with value `Int(42)` when called with `foo` and a +/// `StringLiteral` with value `"str"` when called with `bla`. +pub fn find_assigned_value<'a>(symbol: &str, semantic: &'a SemanticModel<'a>) -> Option<&'a Expr> { + let binding_id = semantic.lookup_symbol(symbol)?; + let binding = semantic.binding(binding_id); + match binding.kind { + // Ex) `x := 1` + BindingKind::NamedExprAssignment => { + let parent_id = binding.source?; + let parent = semantic + .expressions(parent_id) + .find_map(|expr| expr.as_named_expr_expr()); + if let Some(ast::ExprNamedExpr { target, value, .. }) = parent { + return match_value(symbol, target.as_ref(), value.as_ref()); + } + } + // Ex) `x = 1` + BindingKind::Assignment => { + let parent_id = binding.source?; + let parent = semantic.statement(parent_id); + match parent { + Stmt::Assign(ast::StmtAssign { value, targets, .. }) => { + if let Some(target) = targets.iter().find(|target| defines(symbol, target)) { + return match_value(symbol, target, value.as_ref()); + } + } + Stmt::AnnAssign(ast::StmtAnnAssign { + value: Some(value), + target, + .. + }) => { + return match_value(symbol, target, value.as_ref()); + } + _ => {} + } + } + _ => {} + } + None +} + +/// Given a target and value, find the value that's assigned to the given symbol. +fn match_value<'a>(symbol: &str, target: &Expr, value: &'a Expr) -> Option<&'a Expr> { + match target { + Expr::Name(ast::ExprName { id, .. }) if id.as_str() == symbol => Some(value), + Expr::Tuple(ast::ExprTuple { elts, .. }) | Expr::List(ast::ExprList { elts, .. }) => { + match value { + Expr::Tuple(ast::ExprTuple { + elts: value_elts, .. + }) + | Expr::List(ast::ExprList { + elts: value_elts, .. + }) + | Expr::Set(ast::ExprSet { + elts: value_elts, .. + }) => get_value_by_id(symbol, elts, value_elts), + _ => None, + } + } + _ => None, + } +} + +/// Returns `true` if the [`Expr`] defines the symbol. +fn defines(symbol: &str, expr: &Expr) -> bool { + match expr { + Expr::Name(ast::ExprName { id, .. }) => id == symbol, + Expr::Tuple(ast::ExprTuple { elts, .. }) + | Expr::List(ast::ExprList { elts, .. }) + | Expr::Set(ast::ExprSet { elts, .. }) => elts.iter().any(|elt| defines(symbol, elt)), + _ => false, + } +} + +fn get_value_by_id<'a>(target_id: &str, targets: &[Expr], values: &'a [Expr]) -> Option<&'a Expr> { + for (target, value) in targets.iter().zip(values.iter()) { + match target { + Expr::Tuple(ast::ExprTuple { + elts: target_elts, .. + }) + | Expr::List(ast::ExprList { + elts: target_elts, .. + }) + | Expr::Set(ast::ExprSet { + elts: target_elts, .. + }) => { + // Collection types can be mismatched like in: (a, b, [c, d]) = [1, 2, {3, 4}] + match value { + Expr::Tuple(ast::ExprTuple { + elts: value_elts, .. + }) + | Expr::List(ast::ExprList { + elts: value_elts, .. + }) + | Expr::Set(ast::ExprSet { + elts: value_elts, .. + }) => { + if let Some(result) = get_value_by_id(target_id, target_elts, value_elts) { + return Some(result); + } + } + _ => (), + }; + } + Expr::Name(ast::ExprName { id, .. }) => { + if *id == target_id { + return Some(value); + } + } + _ => (), + } + } + None +} diff --git a/crates/ruff_python_semantic/src/model.rs b/crates/ruff_python_semantic/src/model.rs index 42617ddaf7396..d92dab84d0f5c 100644 --- a/crates/ruff_python_semantic/src/model.rs +++ b/crates/ruff_python_semantic/src/model.rs @@ -291,9 +291,12 @@ impl<'a> SemanticModel<'a> { if let Some(binding_id) = self.scopes.global().get(name.id.as_str()) { if !self.bindings[binding_id].is_unbound() { // Mark the binding as used. - let reference_id = - self.resolved_references - .push(ScopeId::global(), name.range, self.flags); + let reference_id = self.resolved_references.push( + ScopeId::global(), + self.node_id, + name.range, + self.flags, + ); self.bindings[binding_id].references.push(reference_id); // Mark any submodule aliases as used. @@ -302,6 +305,7 @@ impl<'a> SemanticModel<'a> { { let reference_id = self.resolved_references.push( ScopeId::global(), + self.node_id, name.range, self.flags, ); @@ -356,18 +360,24 @@ impl<'a> SemanticModel<'a> { if let Some(binding_id) = scope.get(name.id.as_str()) { // Mark the binding as used. - let reference_id = - self.resolved_references - .push(self.scope_id, name.range, self.flags); + let reference_id = self.resolved_references.push( + self.scope_id, + self.node_id, + name.range, + self.flags, + ); self.bindings[binding_id].references.push(reference_id); // Mark any submodule aliases as used. if let Some(binding_id) = self.resolve_submodule(name.id.as_str(), scope_id, binding_id) { - let reference_id = - self.resolved_references - .push(self.scope_id, name.range, self.flags); + let reference_id = self.resolved_references.push( + self.scope_id, + self.node_id, + name.range, + self.flags, + ); self.bindings[binding_id].references.push(reference_id); } @@ -431,9 +441,12 @@ impl<'a> SemanticModel<'a> { // The `x` in `print(x)` should resolve to the `x` in `x = 1`. BindingKind::UnboundException(Some(binding_id)) => { // Mark the binding as used. - let reference_id = - self.resolved_references - .push(self.scope_id, name.range, self.flags); + let reference_id = self.resolved_references.push( + self.scope_id, + self.node_id, + name.range, + self.flags, + ); self.bindings[binding_id].references.push(reference_id); // Mark any submodule aliases as used. @@ -442,6 +455,7 @@ impl<'a> SemanticModel<'a> { { let reference_id = self.resolved_references.push( self.scope_id, + self.node_id, name.range, self.flags, ); @@ -979,6 +993,23 @@ impl<'a> SemanticModel<'a> { &self.nodes[node_id] } + /// Given a [`Expr`], return its parent, if any. + #[inline] + pub fn parent_expression(&self, node_id: NodeId) -> Option<&'a Expr> { + self.nodes + .ancestor_ids(node_id) + .filter_map(|id| self.nodes[id].as_expression()) + .nth(1) + } + + /// Given a [`NodeId`], return the [`NodeId`] of the parent expression, if any. + pub fn parent_expression_id(&self, node_id: NodeId) -> Option { + self.nodes + .ancestor_ids(node_id) + .filter(|id| self.nodes[*id].is_expression()) + .nth(1) + } + /// Return the [`Stmt`] corresponding to the given [`NodeId`]. #[inline] pub fn statement(&self, node_id: NodeId) -> &'a Stmt { @@ -1005,6 +1036,22 @@ impl<'a> SemanticModel<'a> { .nth(1) } + /// Return the [`Expr`] corresponding to the given [`NodeId`]. + #[inline] + pub fn expression(&self, node_id: NodeId) -> Option<&'a Expr> { + self.nodes + .ancestor_ids(node_id) + .find_map(|id| self.nodes[id].as_expression()) + } + + /// Returns an [`Iterator`] over the expressions, starting from the given [`NodeId`]. + /// through to any parents. + pub fn expressions(&self, node_id: NodeId) -> impl Iterator + '_ { + self.nodes + .ancestor_ids(node_id) + .filter_map(move |id| self.nodes[id].as_expression()) + } + /// Set the [`Globals`] for the current [`Scope`]. pub fn set_globals(&mut self, globals: Globals<'a>) { // If any global bindings don't already exist in the global scope, add them. @@ -1169,17 +1216,17 @@ impl<'a> SemanticModel<'a> { /// Add a reference to the given [`BindingId`] in the local scope. pub fn add_local_reference(&mut self, binding_id: BindingId, range: TextRange) { - let reference_id = self - .resolved_references - .push(self.scope_id, range, self.flags); + let reference_id = + self.resolved_references + .push(self.scope_id, self.node_id, range, self.flags); self.bindings[binding_id].references.push(reference_id); } /// Add a reference to the given [`BindingId`] in the global scope. pub fn add_global_reference(&mut self, binding_id: BindingId, range: TextRange) { - let reference_id = self - .resolved_references - .push(ScopeId::global(), range, self.flags); + let reference_id = + self.resolved_references + .push(ScopeId::global(), self.node_id, range, self.flags); self.bindings[binding_id].references.push(reference_id); } @@ -1282,10 +1329,16 @@ impl<'a> SemanticModel<'a> { .intersects(SemanticModelFlags::TYPING_ONLY_ANNOTATION) } - /// Return `true` if the model is in a runtime-required type annotation. - pub const fn in_runtime_annotation(&self) -> bool { + /// Return `true` if the context is in a runtime-evaluated type annotation. + pub const fn in_runtime_evaluated_annotation(&self) -> bool { + self.flags + .intersects(SemanticModelFlags::RUNTIME_EVALUATED_ANNOTATION) + } + + /// Return `true` if the context is in a runtime-required type annotation. + pub const fn in_runtime_required_annotation(&self) -> bool { self.flags - .intersects(SemanticModelFlags::RUNTIME_ANNOTATION) + .intersects(SemanticModelFlags::RUNTIME_REQUIRED_ANNOTATION) } /// Return `true` if the model is in a type definition. @@ -1359,8 +1412,8 @@ impl<'a> SemanticModel<'a> { } /// Return `true` if the model is in a `typing::Literal` annotation. - pub const fn in_literal(&self) -> bool { - self.flags.intersects(SemanticModelFlags::LITERAL) + pub const fn in_typing_literal(&self) -> bool { + self.flags.intersects(SemanticModelFlags::TYPING_LITERAL) } /// Return `true` if the model is in a subscript expression. @@ -1457,8 +1510,9 @@ impl ShadowedBinding { bitflags! { /// Flags indicating the current model state. #[derive(Debug, Default, Copy, Clone, Eq, PartialEq)] - pub struct SemanticModelFlags: u16 { - /// The model is in a typing-time-only type annotation. + pub struct SemanticModelFlags: u32 { + /// The model is in a type annotation that will only be evaluated when running a type + /// checker. /// /// For example, the model could be visiting `int` in: /// ```python @@ -1473,7 +1527,7 @@ bitflags! { /// are any annotated assignments in module or class scopes. const TYPING_ONLY_ANNOTATION = 1 << 0; - /// The model is in a runtime type annotation. + /// The model is in a type annotation that will be evaluated at runtime. /// /// For example, the model could be visiting `int` in: /// ```python @@ -1487,7 +1541,27 @@ bitflags! { /// If `from __future__ import annotations` is used, all annotations are evaluated at /// typing time. Otherwise, all function argument annotations are evaluated at runtime, as /// are any annotated assignments in module or class scopes. - const RUNTIME_ANNOTATION = 1 << 1; + const RUNTIME_EVALUATED_ANNOTATION = 1 << 1; + + /// The model is in a type annotation that is _required_ to be available at runtime. + /// + /// For example, the context could be visiting `int` in: + /// ```python + /// from pydantic import BaseModel + /// + /// class Foo(BaseModel): + /// x: int + /// ``` + /// + /// In this case, Pydantic requires that the type annotation be available at runtime + /// in order to perform runtime type-checking. + /// + /// Unlike [`RUNTIME_EVALUATED_ANNOTATION`], annotations that are marked as + /// [`RUNTIME_REQUIRED_ANNOTATION`] cannot be deferred to typing time via conversion to a + /// forward reference (e.g., by wrapping the type in quotes), as the annotations are not + /// only required by the Python interpreter, but by runtime type checkers too. + const RUNTIME_REQUIRED_ANNOTATION = 1 << 2; + /// The model is in a type definition. /// @@ -1501,7 +1575,7 @@ bitflags! { /// All type annotations are also type definitions, but the converse is not true. /// In our example, `int` is a type definition but not a type annotation, as it /// doesn't appear in a type annotation context, but rather in a type definition. - const TYPE_DEFINITION = 1 << 2; + const TYPE_DEFINITION = 1 << 3; /// The model is in a (deferred) "simple" string type definition. /// @@ -1512,7 +1586,7 @@ bitflags! { /// /// "Simple" string type definitions are those that consist of a single string literal, /// as opposed to an implicitly concatenated string literal. - const SIMPLE_STRING_TYPE_DEFINITION = 1 << 3; + const SIMPLE_STRING_TYPE_DEFINITION = 1 << 4; /// The model is in a (deferred) "complex" string type definition. /// @@ -1523,7 +1597,7 @@ bitflags! { /// /// "Complex" string type definitions are those that consist of a implicitly concatenated /// string literals. These are uncommon but valid. - const COMPLEX_STRING_TYPE_DEFINITION = 1 << 4; + const COMPLEX_STRING_TYPE_DEFINITION = 1 << 5; /// The model is in a (deferred) `__future__` type definition. /// @@ -1536,7 +1610,7 @@ bitflags! { /// /// `__future__`-style type annotations are only enabled if the `annotations` feature /// is enabled via `from __future__ import annotations`. - const FUTURE_TYPE_DEFINITION = 1 << 5; + const FUTURE_TYPE_DEFINITION = 1 << 6; /// The model is in an exception handler. /// @@ -1547,7 +1621,7 @@ bitflags! { /// except Exception: /// x: int = 1 /// ``` - const EXCEPTION_HANDLER = 1 << 6; + const EXCEPTION_HANDLER = 1 << 7; /// The model is in an f-string. /// @@ -1555,7 +1629,7 @@ bitflags! { /// ```python /// f'{x}' /// ``` - const F_STRING = 1 << 7; + const F_STRING = 1 << 8; /// The model is in a boolean test. /// @@ -1567,7 +1641,7 @@ bitflags! { /// /// The implication is that the actual value returned by the current expression is /// not used, only its truthiness. - const BOOLEAN_TEST = 1 << 8; + const BOOLEAN_TEST = 1 << 9; /// The model is in a `typing::Literal` annotation. /// @@ -1576,7 +1650,7 @@ bitflags! { /// def f(x: Literal["A", "B", "C"]): /// ... /// ``` - const LITERAL = 1 << 9; + const TYPING_LITERAL = 1 << 10; /// The model is in a subscript expression. /// @@ -1584,7 +1658,7 @@ bitflags! { /// ```python /// x["a"]["b"] /// ``` - const SUBSCRIPT = 1 << 10; + const SUBSCRIPT = 1 << 11; /// The model is in a type-checking block. /// @@ -1596,7 +1670,7 @@ bitflags! { /// if TYPE_CHECKING: /// x: int = 1 /// ``` - const TYPE_CHECKING_BLOCK = 1 << 11; + const TYPE_CHECKING_BLOCK = 1 << 12; /// The model has traversed past the "top-of-file" import boundary. /// @@ -1609,7 +1683,7 @@ bitflags! { /// /// x: int = 1 /// ``` - const IMPORT_BOUNDARY = 1 << 12; + const IMPORT_BOUNDARY = 1 << 13; /// The model has traversed past the `__future__` import boundary. /// @@ -1624,7 +1698,7 @@ bitflags! { /// /// Python considers it a syntax error to import from `__future__` after /// any other non-`__future__`-importing statements. - const FUTURES_BOUNDARY = 1 << 13; + const FUTURES_BOUNDARY = 1 << 14; /// `__future__`-style type annotations are enabled in this model. /// @@ -1636,7 +1710,7 @@ bitflags! { /// def f(x: int) -> int: /// ... /// ``` - const FUTURE_ANNOTATIONS = 1 << 14; + const FUTURE_ANNOTATIONS = 1 << 15; /// The model is in a type parameter definition. /// @@ -1646,10 +1720,11 @@ bitflags! { /// /// Record = TypeVar("Record") /// - const TYPE_PARAM_DEFINITION = 1 << 15; + const TYPE_PARAM_DEFINITION = 1 << 16; /// The context is in any type annotation. - const ANNOTATION = Self::TYPING_ONLY_ANNOTATION.bits() | Self::RUNTIME_ANNOTATION.bits(); + const ANNOTATION = Self::TYPING_ONLY_ANNOTATION.bits() | Self::RUNTIME_EVALUATED_ANNOTATION.bits() | Self::RUNTIME_REQUIRED_ANNOTATION.bits(); + /// The context is in any string type definition. const STRING_TYPE_DEFINITION = Self::SIMPLE_STRING_TYPE_DEFINITION.bits() diff --git a/crates/ruff_python_semantic/src/reference.rs b/crates/ruff_python_semantic/src/reference.rs index a963895b21e69..6bb807e1c8523 100644 --- a/crates/ruff_python_semantic/src/reference.rs +++ b/crates/ruff_python_semantic/src/reference.rs @@ -8,11 +8,14 @@ use ruff_text_size::{Ranged, TextRange}; use crate::context::ExecutionContext; use crate::scope::ScopeId; -use crate::{Exceptions, SemanticModelFlags}; +use crate::{Exceptions, NodeId, SemanticModelFlags}; /// A resolved read reference to a name in a program. #[derive(Debug, Clone)] pub struct ResolvedReference { + /// The expression that the reference occurs in. `None` if the reference is a global + /// reference or a reference via an augmented assignment. + node_id: Option, /// The scope in which the reference is defined. scope_id: ScopeId, /// The range of the reference in the source code. @@ -22,6 +25,11 @@ pub struct ResolvedReference { } impl ResolvedReference { + /// The expression that the reference occurs in. + pub const fn expression_id(&self) -> Option { + self.node_id + } + /// The scope in which the reference is defined. pub const fn scope_id(&self) -> ScopeId { self.scope_id @@ -35,6 +43,48 @@ impl ResolvedReference { ExecutionContext::Runtime } } + + /// Return `true` if the context is in a typing-only type annotation. + pub const fn in_typing_only_annotation(&self) -> bool { + self.flags + .intersects(SemanticModelFlags::TYPING_ONLY_ANNOTATION) + } + + /// Return `true` if the context is in a runtime-required type annotation. + pub const fn in_runtime_evaluated_annotation(&self) -> bool { + self.flags + .intersects(SemanticModelFlags::RUNTIME_EVALUATED_ANNOTATION) + } + + /// Return `true` if the context is in a "simple" string type definition. + pub const fn in_simple_string_type_definition(&self) -> bool { + self.flags + .intersects(SemanticModelFlags::SIMPLE_STRING_TYPE_DEFINITION) + } + + /// Return `true` if the context is in a "complex" string type definition. + pub const fn in_complex_string_type_definition(&self) -> bool { + self.flags + .intersects(SemanticModelFlags::COMPLEX_STRING_TYPE_DEFINITION) + } + + /// Return `true` if the context is in a `__future__` type definition. + pub const fn in_future_type_definition(&self) -> bool { + self.flags + .intersects(SemanticModelFlags::FUTURE_TYPE_DEFINITION) + } + + /// Return `true` if the context is in any kind of deferred type definition. + pub const fn in_deferred_type_definition(&self) -> bool { + self.flags + .intersects(SemanticModelFlags::DEFERRED_TYPE_DEFINITION) + } + + /// Return `true` if the context is in a type-checking block. + pub const fn in_type_checking_block(&self) -> bool { + self.flags + .intersects(SemanticModelFlags::TYPE_CHECKING_BLOCK) + } } impl Ranged for ResolvedReference { @@ -57,10 +107,12 @@ impl ResolvedReferences { pub(crate) fn push( &mut self, scope_id: ScopeId, + node_id: Option, range: TextRange, flags: SemanticModelFlags, ) -> ResolvedReferenceId { self.0.push(ResolvedReference { + node_id, scope_id, range, flags, diff --git a/crates/ruff_shrinking/Cargo.toml b/crates/ruff_shrinking/Cargo.toml index caa568c997f35..f655da8bab610 100644 --- a/crates/ruff_shrinking/Cargo.toml +++ b/crates/ruff_shrinking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff_shrinking" -version = "0.1.6" +version = "0.1.8" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -8,7 +8,7 @@ edition = "2021" [dependencies] anyhow = { workspace = true } clap = { workspace = true } -fs-err = "2.10.0" +fs-err = "2.11.0" regex = { workspace = true } ruff_python_ast = { path = "../ruff_python_ast" } ruff_python_parser = { path = "../ruff_python_parser" } diff --git a/crates/ruff_source_file/src/newlines.rs b/crates/ruff_source_file/src/newlines.rs index 6a79878fe4399..4e4d4e09a4a3e 100644 --- a/crates/ruff_source_file/src/newlines.rs +++ b/crates/ruff_source_file/src/newlines.rs @@ -58,11 +58,7 @@ impl<'a> UniversalNewlineIterator<'a> { pub fn find_newline(text: &str) -> Option<(usize, LineEnding)> { let bytes = text.as_bytes(); if let Some(position) = memchr2(b'\n', b'\r', bytes) { - // SAFETY: memchr guarantees to return valid positions - #[allow(unsafe_code)] - let newline_character = unsafe { *bytes.get_unchecked(position) }; - - let line_ending = match newline_character { + let line_ending = match bytes[position] { // Explicit branch for `\n` as this is the most likely path b'\n' => LineEnding::Lf, // '\r\n' diff --git a/crates/ruff_wasm/Cargo.toml b/crates/ruff_wasm/Cargo.toml index d8884eb14a6a6..7b5875a0bc440 100644 --- a/crates/ruff_wasm/Cargo.toml +++ b/crates/ruff_wasm/Cargo.toml @@ -36,12 +36,12 @@ console_log = { version = "1.0.0" } log = { workspace = true } serde = { workspace = true } -serde-wasm-bindgen = { version = "0.6.1" } +serde-wasm-bindgen = { version = "0.6.3" } wasm-bindgen = { version = "0.2.84" } -js-sys = { version = "0.3.61" } +js-sys = { version = "0.3.66" } [dev-dependencies] -wasm-bindgen-test = { version = "0.3.34" } +wasm-bindgen-test = { version = "0.3.38" } [lints] workspace = true diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index bd4af7853f3b2..ed1d0cb6eb3c9 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -34,7 +34,9 @@ use ruff_linter::settings::{ use ruff_linter::{ fs, warn_user, warn_user_once, warn_user_once_by_id, RuleSelector, RUFF_PKG_VERSION, }; -use ruff_python_formatter::{MagicTrailingComma, QuoteStyle}; +use ruff_python_formatter::{ + DocstringCode, DocstringCodeLineWidth, MagicTrailingComma, QuoteStyle, +}; use crate::options::{ Flake8AnnotationsOptions, Flake8BanditOptions, Flake8BugbearOptions, Flake8BuiltinsOptions, @@ -158,12 +160,21 @@ impl Configuration { let format = self.format; let format_defaults = FormatterSettings::default(); + let quote_style = format.quote_style.unwrap_or(format_defaults.quote_style); + let format_preview = match format.preview.unwrap_or(global_preview) { + PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled, + PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled, + }; + + if quote_style == QuoteStyle::Preserve && !format_preview.is_enabled() { + return Err(anyhow!( + "'quote-style = preserve' is a preview only feature. Run with '--preview' to enable it." + )); + } + let formatter = FormatterSettings { exclude: FilePatternSet::try_from_iter(format.exclude.unwrap_or_default())?, - preview: match format.preview.unwrap_or(global_preview) { - PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled, - PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled, - }, + preview: format_preview, line_width: self .line_length .map_or(format_defaults.line_width, |length| { @@ -176,10 +187,16 @@ impl Configuration { .map_or(format_defaults.indent_width, |tab_size| { ruff_formatter::IndentWidth::from(NonZeroU8::from(tab_size)) }), - quote_style: format.quote_style.unwrap_or(format_defaults.quote_style), + quote_style, magic_trailing_comma: format .magic_trailing_comma .unwrap_or(format_defaults.magic_trailing_comma), + docstring_code_format: format + .docstring_code_format + .unwrap_or(format_defaults.docstring_code_format), + docstring_code_line_width: format + .docstring_code_line_width + .unwrap_or(format_defaults.docstring_code_line_width), }; let lint = self.lint; @@ -1011,6 +1028,8 @@ pub struct FormatConfiguration { pub quote_style: Option, pub magic_trailing_comma: Option, pub line_ending: Option, + pub docstring_code_format: Option, + pub docstring_code_line_width: Option, } impl FormatConfiguration { @@ -1037,6 +1056,14 @@ impl FormatConfiguration { } }), line_ending: options.line_ending, + docstring_code_format: options.docstring_code_format.map(|yes| { + if yes { + DocstringCode::Enabled + } else { + DocstringCode::Disabled + } + }), + docstring_code_line_width: options.docstring_code_line_length, }) } @@ -1050,6 +1077,10 @@ impl FormatConfiguration { quote_style: self.quote_style.or(other.quote_style), magic_trailing_comma: self.magic_trailing_comma.or(other.magic_trailing_comma), line_ending: self.line_ending.or(other.line_ending), + docstring_code_format: self.docstring_code_format.or(other.docstring_code_format), + docstring_code_line_width: self + .docstring_code_line_width + .or(other.docstring_code_line_width), } } } diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index 5967186b444a9..b032c2be3acf5 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -27,7 +27,7 @@ use ruff_linter::settings::types::{ }; use ruff_linter::{warn_user_once, RuleSelector}; use ruff_macros::{CombineOptions, OptionsMetadata}; -use ruff_python_formatter::QuoteStyle; +use ruff_python_formatter::{DocstringCodeLineWidth, QuoteStyle}; use crate::settings::LineEnding; @@ -93,8 +93,10 @@ pub struct Options { pub fix: Option, /// Enable application of unsafe fixes. + /// If excluded, a hint will be displayed when unsafe fixes are available. + /// If set to false, the hint will be hidden. #[option( - default = "false", + default = r#"null"#, value_type = "bool", example = "unsafe-fixes = true" )] @@ -1640,6 +1642,57 @@ pub struct Flake8TypeCheckingOptions { "# )] pub runtime_evaluated_decorators: Option>, + + /// Whether to add quotes around type annotations, if doing so would allow + /// the corresponding import to be moved into a type-checking block. + /// + /// For example, in the following, Python requires that `Sequence` be + /// available at runtime, despite the fact that it's only used in a type + /// annotation: + /// + /// ```python + /// from collections.abc import Sequence + /// + /// + /// def func(value: Sequence[int]) -> None: + /// ... + /// ``` + /// + /// In other words, moving `from collections.abc import Sequence` into an + /// `if TYPE_CHECKING:` block above would cause a runtime error, as the + /// type would no longer be available at runtime. + /// + /// By default, Ruff will respect such runtime semantics and avoid moving + /// the import to prevent such runtime errors. + /// + /// Setting `quote-annotations` to `true` will instruct Ruff to add quotes + /// around the annotation (e.g., `"Sequence[int]"`), which in turn enables + /// Ruff to move the import into an `if TYPE_CHECKING:` block, like so: + /// + /// ```python + /// from typing import TYPE_CHECKING + /// + /// if TYPE_CHECKING: + /// from collections.abc import Sequence + /// + /// + /// def func(value: "Sequence[int]") -> None: + /// ... + /// ``` + /// + /// Note that this setting has no effect when `from __future__ import annotations` + /// is present, as `__future__` annotations are always treated equivalently + /// to quoted annotations. + #[option( + default = "false", + value_type = "bool", + example = r#" + # Add quotes around type annotations, if doing so would allow + # an import to be moved into a type-checking block. + quote-annotations = true + "# + )] + pub quote_annotations: Option, } impl Flake8TypeCheckingOptions { @@ -1649,8 +1702,9 @@ impl Flake8TypeCheckingOptions { exempt_modules: self .exempt_modules .unwrap_or_else(|| vec!["typing".to_string()]), - runtime_evaluated_base_classes: self.runtime_evaluated_base_classes.unwrap_or_default(), - runtime_evaluated_decorators: self.runtime_evaluated_decorators.unwrap_or_default(), + runtime_required_base_classes: self.runtime_evaluated_base_classes.unwrap_or_default(), + runtime_required_decorators: self.runtime_evaluated_decorators.unwrap_or_default(), + quote_annotations: self.quote_annotations.unwrap_or_default(), } } } @@ -2021,6 +2075,66 @@ pub struct IsortOptions { )] pub detect_same_package: Option, + /// Whether to place `import from` imports before straight imports when sorting. + /// + /// For example, by default, imports will be sorted such that straight imports appear + /// before `import from` imports, as in: + /// ```python + /// import os + /// import sys + /// from typing import List + /// ``` + /// + /// Setting `from-first = true` will instead sort such that `import from` imports appear + /// before straight imports, as in: + /// ```python + /// from typing import List + /// import os + /// import sys + /// ``` + #[option( + default = r#"false"#, + value_type = "bool", + example = r#" + from-first = true + "# + )] + pub from_first: Option, + + /// Sort imports by their string length, such that shorter imports appear + /// before longer imports. For example, by default, imports will be sorted + /// alphabetically, as in: + /// ```python + /// import collections + /// import os + /// ``` + /// + /// Setting `length-sort = true` will instead sort such that shorter imports + /// appear before longer imports, as in: + /// ```python + /// import os + /// import collections + /// ``` + #[option( + default = r#"false"#, + value_type = "bool", + example = r#" + length-sort = true + "# + )] + pub length_sort: Option, + + /// Sort straight imports by their string length. Similar to `length-sort`, + /// but applies only to straight imports and doesn't affect `from` imports. + #[option( + default = r#"false"#, + value_type = "bool", + example = r#" + length-sort-straight = true + "# + )] + pub length_sort_straight: Option, + // Tables are required to go last. /// A list of mappings from section names to modules. /// By default custom sections are output last, but this can be overridden with `section-order`. @@ -2049,6 +2163,13 @@ impl IsortOptions { warn_user_once!("`sections` is ignored when `no-sections` is set to `true`"); } + // Verify that if `force_sort_within_sections` is `True`, then `lines_between_types` is set to `0`. + let force_sort_within_sections = self.force_sort_within_sections.unwrap_or_default(); + let lines_between_types = self.lines_between_types.unwrap_or_default(); + if force_sort_within_sections && lines_between_types != 0 { + warn_user_once!("`lines-between-types` is ignored when `force-sort-within-sections` is set to `true`"); + } + // Extract any configuration options that deal with user-defined sections. let mut section_order: Vec<_> = self .section_order @@ -2098,6 +2219,7 @@ impl IsortOptions { .map_err(isort::settings::SettingsError::InvalidExtraStandardLibrary)? .unwrap_or_default(); let no_lines_before = self.no_lines_before.unwrap_or_default(); + let from_first = self.from_first.unwrap_or_default(); let sections = self.sections.unwrap_or_default(); // Verify that `sections` doesn't contain any built-in sections. @@ -2179,7 +2301,7 @@ impl IsortOptions { required_imports: BTreeSet::from_iter(self.required_imports.unwrap_or_default()), combine_as_imports: self.combine_as_imports.unwrap_or(false), force_single_line: self.force_single_line.unwrap_or(false), - force_sort_within_sections: self.force_sort_within_sections.unwrap_or(false), + force_sort_within_sections, case_sensitive: self.case_sensitive.unwrap_or(false), force_wrap_aliases: self.force_wrap_aliases.unwrap_or(false), detect_same_package: self.detect_same_package.unwrap_or(true), @@ -2202,10 +2324,13 @@ impl IsortOptions { variables: BTreeSet::from_iter(self.variables.unwrap_or_default()), no_lines_before: BTreeSet::from_iter(no_lines_before), lines_after_imports: self.lines_after_imports.unwrap_or(-1), - lines_between_types: self.lines_between_types.unwrap_or_default(), + lines_between_types, forced_separate: Vec::from_iter(self.forced_separate.unwrap_or_default()), section_order, no_sections, + from_first, + length_sort: self.length_sort.unwrap_or(false), + length_sort_straight: self.length_sort_straight.unwrap_or(false), }) } } @@ -2545,6 +2670,17 @@ pub struct PylintOptions { )] pub allow_magic_value_types: Option>, + /// Dunder methods name to allow, in addition to the default set from the + /// Python standard library (see: `PLW3201`). + #[option( + default = r#"[]"#, + value_type = r#"list[str]"#, + example = r#" + allow-dunder-method-names = ["__tablename__", "__table_args__"] + "# + )] + pub allow_dunder_method_names: Option>, + /// Maximum number of branches allowed for a function or method body (see: /// `PLR0912`). #[option(default = r"12", value_type = "int", example = r"max-branches = 12")] @@ -2560,6 +2696,13 @@ pub struct PylintOptions { #[option(default = r"5", value_type = "int", example = r"max-args = 5")] pub max_args: Option, + /// Maximum number of positional arguments allowed for a function or method definition + /// (see: `PLR0917`). + /// + /// If not specified, defaults to the value of `max-args`. + #[option(default = r"3", value_type = "int", example = r"max-pos-args = 3")] + pub max_positional_args: Option, + /// Maximum number of statements allowed for a function or method body (see: /// `PLR0915`). #[option(default = r"50", value_type = "int", example = r"max-statements = 50")] @@ -2586,7 +2729,12 @@ impl PylintOptions { allow_magic_value_types: self .allow_magic_value_types .unwrap_or(defaults.allow_magic_value_types), + allow_dunder_method_names: self.allow_dunder_method_names.unwrap_or_default(), max_args: self.max_args.unwrap_or(defaults.max_args), + max_positional_args: self + .max_positional_args + .or(self.max_args) + .unwrap_or(defaults.max_positional_args), max_bool_expr: self.max_bool_expr.unwrap_or(defaults.max_bool_expr), max_returns: self.max_returns.unwrap_or(defaults.max_returns), max_branches: self.max_branches.unwrap_or(defaults.max_branches), @@ -2725,13 +2873,18 @@ pub struct FormatOptions { )] pub indent_style: Option, - /// Whether to prefer single `'` or double `"` quotes for strings. Defaults to double quotes. + /// Configures the preferred quote character for strings. Valid options are: + /// + /// * `double` (default): Use double quotes `"` + /// * `single`: Use single quotes `'` + /// * `preserve` (preview only): Keeps the existing quote character. We don't recommend using this option except for projects + /// that already use a mixture of single and double quotes and can't migrate to using double or single quotes. /// /// In compliance with [PEP 8](https://peps.python.org/pep-0008/) and [PEP 257](https://peps.python.org/pep-0257/), /// Ruff prefers double quotes for multiline strings and docstrings, regardless of the /// configured quote style. /// - /// Ruff may also deviate from this option if using the configured quotes would require + /// Ruff may also deviate from using the configured quotes if doing so requires /// escaping quote characters within the string. For example, given: /// /// ```python @@ -2740,11 +2893,11 @@ pub struct FormatOptions { /// ``` /// /// Ruff will change `a` to use single quotes when using `quote-style = "single"`. However, - /// `b` will be unchanged, as converting to single quotes would require the inner `'` to be - /// escaped, which leads to less readable code: `'It\'s monday morning'`. + /// `b` remains unchanged, as converting to single quotes requires escaping the inner `'`, + /// which leads to less readable code: `'It\'s monday morning'`. This does not apply when using `preserve`. #[option( default = r#"double"#, - value_type = r#""double" | "single""#, + value_type = r#""double" | "single" | "preserve""#, example = r#" # Prefer single quotes over double quotes. quote-style = "single" @@ -2795,6 +2948,156 @@ pub struct FormatOptions { "# )] pub line_ending: Option, + + /// Whether to format code snippets in docstrings. + /// + /// When this is enabled, Python code examples within docstrings are + /// automatically reformatted. + /// + /// For example, when this is enabled, the following code: + /// + /// ```python + /// def f(x): + /// """ + /// Something about `f`. And an example in doctest format: + /// + /// >>> f( x ) + /// + /// Markdown is also supported: + /// + /// ```py + /// f( x ) + /// ``` + /// + /// As are reStructuredText literal blocks:: + /// + /// f( x ) + /// + /// + /// And reStructuredText code blocks: + /// + /// .. code-block:: python + /// + /// f( x ) + /// """ + /// pass + /// ``` + /// + /// ... will be reformatted (assuming the rest of the options are set to + /// their defaults) as: + /// + /// ```python + /// def f(x): + /// """ + /// Something about `f`. And an example in doctest format: + /// + /// >>> f(x) + /// + /// Markdown is also supported: + /// + /// ```py + /// f(x) + /// ``` + /// + /// As are reStructuredText literal blocks:: + /// + /// f(x) + /// + /// + /// And reStructuredText code blocks: + /// + /// .. code-block:: python + /// + /// f(x) + /// """ + /// pass + /// ``` + /// + /// If a code snippt in a docstring contains invalid Python code or if the + /// formatter would otherwise write invalid Python code, then the code + /// example is ignored by the formatter and kept as-is. + /// + /// Currently, doctest, Markdown, reStructuredText literal blocks, and + /// reStructuredText code blocks are all supported and automatically + /// recognized. In the case of unlabeled fenced code blocks in Markdown and + /// reStructuredText literal blocks, the contents are assumed to be Python + /// and reformatted. As with any other format, if the contents aren't valid + /// Python, then the block is left untouched automatically. + #[option( + default = "false", + value_type = "bool", + example = r#" + # Enable reformatting of code snippets in docstrings. + docstring-code-format = true + "# + )] + pub docstring_code_format: Option, + + /// Set the line length used when formatting code snippets in docstrings. + /// + /// This only has an effect when the `docstring-code-format` setting is + /// enabled. + /// + /// The default value for this setting is `"dynamic"`, which has the effect + /// of ensuring that any reformatted code examples in docstrings adhere to + /// the global line length configuration that is used for the surrounding + /// Python code. The point of this setting is that it takes the indentation + /// of the docstring into account when reformatting code examples. + /// + /// Alternatively, this can be set to a fixed integer, which will result + /// in the same line length limit being applied to all reformatted code + /// examples in docstrings. When set to a fixed integer, the indent of the + /// docstring is not taken into account. That is, this may result in lines + /// in the reformatted code example that exceed the globally configured + /// line length limit. + /// + /// For example, when this is set to `20` and `docstring-code-format` is + /// enabled, then this code: + /// + /// ```python + /// def f(x): + /// ''' + /// Something about `f`. And an example: + /// + /// .. code-block:: python + /// + /// foo, bar, quux = this_is_a_long_line(lion, hippo, lemur, bear) + /// ''' + /// pass + /// ``` + /// + /// ... will be reformatted (assuming the rest of the options are set + /// to their defaults) as: + /// + /// ```python + /// def f(x): + /// """ + /// Something about `f`. And an example: + /// + /// .. code-block:: python + /// + /// ( + /// foo, + /// bar, + /// quux, + /// ) = this_is_a_long_line( + /// lion, + /// hippo, + /// lemur, + /// bear, + /// ) + /// """ + /// pass + /// ``` + #[option( + default = r#""dynamic""#, + value_type = r#"int | "dynamic""#, + example = r#" + # Format all docstring code snippets with a line length of 60. + docstring-code-line-length = 60 + "# + )] + pub docstring_code_line_length: Option, } #[cfg(test)] diff --git a/crates/ruff_workspace/src/resolver.rs b/crates/ruff_workspace/src/resolver.rs index fc12feaad3ace..93df74b1e2aad 100644 --- a/crates/ruff_workspace/src/resolver.rs +++ b/crates/ruff_workspace/src/resolver.rs @@ -294,6 +294,7 @@ pub fn python_files_in_path( let (root, settings) = resolve_scoped_settings(&pyproject, Relativity::Parent, transformer)?; resolver.add(root, settings); + break; } } } @@ -494,6 +495,7 @@ pub fn python_file_at_path( let (root, settings) = resolve_scoped_settings(&pyproject, Relativity::Parent, transformer)?; resolver.add(root, settings); + break; } } } diff --git a/crates/ruff_workspace/src/settings.rs b/crates/ruff_workspace/src/settings.rs index 982732e487317..8ee030ea3b42a 100644 --- a/crates/ruff_workspace/src/settings.rs +++ b/crates/ruff_workspace/src/settings.rs @@ -5,7 +5,10 @@ use ruff_linter::settings::types::{FilePattern, FilePatternSet, SerializationFor use ruff_linter::settings::LinterSettings; use ruff_macros::CacheKey; use ruff_python_ast::PySourceType; -use ruff_python_formatter::{MagicTrailingComma, PreviewMode, PyFormatOptions, QuoteStyle}; +use ruff_python_formatter::{ + DocstringCode, DocstringCodeLineWidth, MagicTrailingComma, PreviewMode, PyFormatOptions, + QuoteStyle, +}; use ruff_source_file::find_newline; use std::path::{Path, PathBuf}; @@ -124,6 +127,9 @@ pub struct FormatterSettings { pub magic_trailing_comma: MagicTrailingComma, pub line_ending: LineEnding, + + pub docstring_code_format: DocstringCode, + pub docstring_code_line_width: DocstringCodeLineWidth, } impl FormatterSettings { @@ -157,6 +163,8 @@ impl FormatterSettings { .with_preview(self.preview) .with_line_ending(line_ending) .with_line_width(self.line_width) + .with_docstring_code(self.docstring_code_format) + .with_docstring_code_line_width(self.docstring_code_line_width) } } @@ -173,6 +181,8 @@ impl Default for FormatterSettings { indent_width: default_options.indent_width(), quote_style: default_options.quote_style(), magic_trailing_comma: default_options.magic_trailing_comma(), + docstring_code_format: default_options.docstring_code(), + docstring_code_line_width: default_options.docstring_code_line_width(), } } } diff --git a/docs/configuration.md b/docs/configuration.md index bc950ad3ac314..ec1dd0fa577df 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -71,6 +71,20 @@ If left unspecified, Ruff's default configuration is equivalent to: # Like Black, automatically detect the appropriate line ending. line-ending = "auto" + + # Enable auto-formatting of code examples in docstrings. Markdown, + # reStructuredText code/literal blocks and doctests are all supported. + # + # This is currently disabled by default, but it is planned for this + # to be opt-out in the future. + docstring-code-format = false + + # Set the line length limit used when formatting code snippets in + # docstrings. + # + # This only has an effect when the `docstring-code-format` setting is + # enabled. + docstring-code-line-length = "dynamic" ``` === "ruff.toml" @@ -134,6 +148,20 @@ If left unspecified, Ruff's default configuration is equivalent to: # Like Black, automatically detect the appropriate line ending. line-ending = "auto" + + # Enable auto-formatting of code examples in docstrings. Markdown, + # reStructuredText code/literal blocks and doctests are all supported. + # + # This is currently disabled by default, but it is planned for this + # to be opt-out in the future. + docstring-code-format = false + + # Set the line length limit used when formatting code snippets in + # docstrings. + # + # This only has an effect when the `docstring-code-format` setting is + # enabled. + docstring-code-line-length = "dynamic" ``` As an example, the following would configure Ruff to: @@ -299,6 +327,45 @@ By default, Ruff will also skip any files that are omitted via `.ignore`, `.giti Files that are passed to `ruff` directly are always analyzed, regardless of the above criteria. For example, `ruff check /path/to/excluded/file.py` will always lint `file.py`. +### Default inclusions + +By default, Ruff will discover files matching `*.py`, `*.ipy`, or `pyproject.toml`. + +To lint or format files with additional file extensions, use the [`extend-include`](settings.md#extend-include) setting. + +=== "pyproject.toml" + + ```toml + [tool.ruff] + extend-include = ["*.ipynb"] + ``` + +=== "ruff.toml" + + ```toml + extend-include = ["*.ipynb"] + ``` + +You can also change the default selection using the [`include`](settings.md#include) setting. + + +=== "pyproject.toml" + + ```toml + [tool.ruff] + include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py"] + ``` + +=== "ruff.toml" + + ```toml + include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py"] + ``` + +!!! warning + Paths provided to `include` _must_ match files. For example, `include = ["src"]` will fail since it + matches a directory. + ## Jupyter Notebook discovery Ruff has built-in support for [Jupyter Notebooks](https://jupyter.org/). @@ -422,7 +489,7 @@ Run Ruff on the given files or directories (default) Usage: ruff check [OPTIONS] [FILES]... Arguments: - [FILES]... List of files or directories to check + [FILES]... List of files or directories to check [default: .] Options: --fix @@ -442,7 +509,7 @@ Options: --ignore-noqa Ignore any `# noqa` comments --output-format - Output serialization format for violations [env: RUFF_OUTPUT_FORMAT=] [possible values: text, json, json-lines, junit, grouped, github, gitlab, pylint, azure] + Output serialization format for violations [env: RUFF_OUTPUT_FORMAT=] [possible values: text, json, json-lines, junit, grouped, github, gitlab, pylint, azure, sarif] -o, --output-file Specify file to write the linter output to (default: stdout) --target-version @@ -518,7 +585,7 @@ Run the Ruff formatter on the given files or directories Usage: ruff format [OPTIONS] [FILES]... Arguments: - [FILES]... List of files or directories to format + [FILES]... List of files or directories to format [default: .] Options: --check diff --git a/docs/formatter.md b/docs/formatter.md index caa7459e55b3d..547f32eee25da 100644 --- a/docs/formatter.md +++ b/docs/formatter.md @@ -1,7 +1,10 @@ # The Ruff Formatter The Ruff formatter is an extremely fast Python code formatter designed as a drop-in replacement for -[Black](https://pypi.org/project/black/), available as part of the `ruff` CLI (as of Ruff v0.0.289). +[Black](https://pypi.org/project/black/), available as part of the `ruff` CLI via `ruff format`. + +The Ruff formatter is available as a [production-ready Beta](https://astral.sh/blog/the-ruff-formatter) +as of Ruff v0.1.2. ## `ruff format` @@ -19,6 +22,10 @@ and instead exit with a non-zero status code upon detecting any unformatted file For the full list of supported options, run `ruff format --help`. +!!! note + As of Ruff v0.1.7 the `ruff format` command uses the current working directory (`.`) as the default path to format. + See [the file discovery documentation](configuration.md#python-file-discovery) for details. + ## Philosophy The initial goal of the Ruff formatter is _not_ to innovate on code style, but rather, to innovate @@ -96,10 +103,12 @@ Going forward, the Ruff Formatter will support Black's preview style under Ruff' ## Configuration The Ruff Formatter exposes a small set of configuration options, some of which are also supported -by Black (like line width), some of which are unique to Ruff (like quote and indentation style). +by Black (like line width), some of which are unique to Ruff (like quote, indentation style and +formatting code examples in docstrings). -For example, to configure the formatter to use single quotes, a line width of 100, and -tab indentation, add the following to your configuration file: +For example, to configure the formatter to use single quotes, format code +examples in docstrings, a line width of 100, and tab indentation, add the +following to your configuration file: === "pyproject.toml" @@ -110,6 +119,7 @@ tab indentation, add the following to your configuration file: [tool.ruff.format] quote-style = "single" indent-style = "tab" + docstring-code-format = true ``` === "ruff.toml" @@ -120,6 +130,7 @@ tab indentation, add the following to your configuration file: [format] quote-style = "single" indent-style = "tab" + docstring-code-format = true ``` @@ -130,6 +141,97 @@ Given the focus on Black compatibility (and unlike formatters like [YAPF](https: Ruff does not currently expose any configuration options to modify core formatting behavior outside of these trivia-related settings. +## Docstring formatting + +The Ruff formatter provides an opt-in feature for automatically formatting +Python code examples in docstrings. The Ruff formatter currently recognizes +code examples in the following formats: + +* The Python [doctest] format. +* CommonMark [fenced code blocks] with the following info strings: `python`, +`py`, `python3`, or `py3`. Fenced code blocks without an info string are +assumed to be Python code examples and also formatted. +* reStructuredText [literal blocks]. While literal blocks may contain things +other than Python, this is meant to reflect a long-standing convention in the +Python ecosystem where literal blocks often contain Python code. +* reStructuredText [`code-block` and `sourcecode` directives]. As with +Markdown, the language names recognized for Python are `python`, `py`, +`python3`, or `py3`. + +If a code example is recognized and treated as Python, the Ruff formatter will +automatically skip it if the code does not parse as valid Python or if the +reformatted code would produce an invalid Python program. + +Users may also configure the line length limit used for reformatting Python +code examples in docstrings. The default is a special value, `dynamic`, which +instructs the formatter to respect the line length limit setting for the +surrounding Python code. The `dynamic` setting ensures that even when code +examples are found inside indented docstrings, the line length limit configured +for the surrounding Python code will not be exceeded. Users may also configure +a fixed line length limit for code examples in docstrings. + +For example, this configuration shows how to enable docstring code formatting +with a fixed line length limit: + +=== "pyproject.toml" + + ```toml + [tool.ruff.format] + docstring-code-format = true + docstring-code-line-length = 20 + ``` + +=== "ruff.toml" + + ```toml + [format] + docstring-code-format = true + docstring-code-line-length = 20 + ``` + +With the above configuration, this code: + +```python +def f(x): + ''' + Something about `f`. And an example: + + .. code-block:: python + + foo, bar, quux = this_is_a_long_line(lion, hippo, lemur, bear) + ''' + pass +``` + +... will be reformatted (assuming the rest of the options are set +to their defaults) as: + +```python +def f(x): + """ + Something about `f`. And an example: + + .. code-block:: python + + ( + foo, + bar, + quux, + ) = this_is_a_long_line( + lion, + hippo, + lemur, + bear, + ) + """ + pass +``` + +[doctest]: https://docs.python.org/3/library/doctest.html +[fenced code blocks]: https://spec.commonmark.org/0.30/#fenced-code-blocks +[literal blocks]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks +[`code-block` and `sourcecode` directives]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block + ## Format suppression Like Black, Ruff supports `# fmt: on`, `# fmt: off`, and `# fmt: skip` pragma comments, which can @@ -290,3 +392,15 @@ flag. Black promotes some of its preview styling to stable at the end of each year. Ruff will similarly implement formatting changes under the [`preview`](https://docs.astral.sh/ruff/settings/#preview) flag, promoting them to stable through minor releases, in accordance with our [versioning policy](https://github.com/astral-sh/ruff/discussions/6998#discussioncomment-7016766). + +## Sorting imports + +Currently, the Ruff formatter does not sort imports. In order to both sort imports and format, +call the Ruff linter and then the formatter: + +```shell +ruff check --select I --fix . +ruff format . +``` + +A unified command for both linting and formatting is [planned](https://github.com/astral-sh/ruff/issues/8232). diff --git a/docs/installation.md b/docs/installation.md index 919289d14b854..a5ef50f35018a 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -27,7 +27,14 @@ For **Conda** users, Ruff is also available as [`ruff`](https://anaconda.org/con conda install -c conda-forge ruff ``` -For **Arch Linux** users, Ruff is also available as [`ruff`](https://archlinux.org/packages/community/x86_64/ruff/) +For **pkgx** users, Ruff is also available as [`ruff`](https://pkgx.dev/pkgs/github.com/charliermarsh/ruff/) +on the `pkgx` registry: + +```shell +pkgx install ruff +``` + +For **Arch Linux** users, Ruff is also available as [`ruff`](https://archlinux.org/packages/extra/x86_64/ruff/) on the official repositories: ```shell @@ -41,6 +48,12 @@ on the testing repositories: apk add ruff ``` +For **openSUSE Tumbleweed** users, Ruff is also available in the distribution repository: + +```shell +sudo zypper install python3-ruff +``` + On **Docker**, it is published as `ghcr.io/astral-sh/ruff`, tagged for each release and `latest` for the latest release. diff --git a/docs/integrations.md b/docs/integrations.md index c9babce79c06a..50ae43c9ca1e7 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -14,7 +14,7 @@ Ruff can be used as a [pre-commit](https://pre-commit.com) hook via [`ruff-pre-c ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.6 + rev: v0.1.8 hooks: # Run the linter. - id: ruff @@ -27,7 +27,7 @@ To enable lint fixes, add the `--fix` argument to the lint hook: ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.6 + rev: v0.1.8 hooks: # Run the linter. - id: ruff @@ -41,7 +41,7 @@ To run the hooks over Jupyter Notebooks too, add `jupyter` to the list of allowe ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.6 + rev: v0.1.8 hooks: # Run the linter. - id: ruff diff --git a/docs/linter.md b/docs/linter.md index 71c5d04ef20aa..5594789dad49f 100644 --- a/docs/linter.md +++ b/docs/linter.md @@ -18,6 +18,10 @@ ruff check . --watch # Lint all files in the current directory, and re-lint on For the full list of supported options, run `ruff check --help`. +!!! note + As of Ruff v0.1.7 the `ruff check` command uses the current working directory (`.`) as the default path to check. + See [the file discovery documentation](configuration.md#python-file-discovery) for details. + ## Rule selection The set of enabled rules is controlled via the [`select`](settings.md#select), @@ -199,6 +203,9 @@ ruff check . --unsafe-fixes ruff check . --fix --unsafe-fixes ``` +By default, Ruff will display a hint when unsafe fixes are available but not enabled. The suggestion can be silenced +by setting the [`unsafe-fixes`](settings.md#unsafe-fixes) setting to `false` or using the `--no-unsafe-fixes` flag. + The safety of fixes can be adjusted per rule using the [`extend-safe-fixes`](settings.md#extend-safe-fixes) and [`extend-unsafe-fixes`](settings.md#extend-unsafe-fixes) settings. For example, the following configuration would promote unsafe fixes for `F601` to safe fixes and demote safe fixes for `UP034` to unsafe fixes: diff --git a/pyproject.toml b/pyproject.toml index 3d9facb8c9692..9a1a059a9a222 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "ruff" -version = "0.1.6" +version = "0.1.8" description = "An extremely fast Python linter and code formatter, written in Rust." authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }] readme = "README.md" diff --git a/python/ruff-ecosystem/ruff_ecosystem/check.py b/python/ruff-ecosystem/ruff_ecosystem/check.py index 2e996ff006773..89d4320570858 100644 --- a/python/ruff-ecosystem/ruff_ecosystem/check.py +++ b/python/ruff-ecosystem/ruff_ecosystem/check.py @@ -52,6 +52,8 @@ def markdown_check_result(result: Result) -> str: """ Render a `ruff check` ecosystem check result as markdown. """ + projects_with_changes = 0 + # Calculate the total number of rule changes all_rule_changes = RuleChanges() project_diffs = { @@ -63,7 +65,10 @@ def markdown_check_result(result: Result) -> str: project_rule_changes[project] = changes = RuleChanges.from_diff(diff) all_rule_changes.update(changes) - lines = [] + if diff: + projects_with_changes += 1 + + lines: list[str] = [] total_removed = all_rule_changes.total_removed_violations() total_added = all_rule_changes.total_added_violations() total_added_fixes = all_rule_changes.total_added_fixes() @@ -88,11 +93,17 @@ def markdown_check_result(result: Result) -> str: change_summary = ( f"{markdown_plus_minus(total_added, total_removed)} violations, " f"{markdown_plus_minus(total_added_fixes, total_removed_fixes)} fixes " - f"in {len(result.completed)} projects" + f"in {projects_with_changes} projects" ) if error_count: s = "s" if error_count != 1 else "" change_summary += f"; {error_count} project error{s}" + + unchanged_projects = len(result.completed) - projects_with_changes + if unchanged_projects: + s = "s" if unchanged_projects != 1 else "" + change_summary += f"; {unchanged_projects} project{s} unchanged" + lines.append( f"\u2139\ufe0f ecosystem check **detected linter changes**. ({change_summary})" ) diff --git a/python/ruff-ecosystem/ruff_ecosystem/format.py b/python/ruff-ecosystem/ruff_ecosystem/format.py index f639150a8680f..b448c208da81d 100644 --- a/python/ruff-ecosystem/ruff_ecosystem/format.py +++ b/python/ruff-ecosystem/ruff_ecosystem/format.py @@ -25,11 +25,12 @@ def markdown_format_result(result: Result) -> str: """ Render a `ruff format` ecosystem check result as markdown. """ - lines = [] + lines: list[str] = [] total_lines_removed = total_lines_added = 0 total_files_modified = 0 + projects_with_changes = 0 error_count = len(result.errored) - patch_sets = [] + patch_sets: list[PatchSet] = [] for project, comparison in result.completed: total_lines_added += comparison.diff.lines_added @@ -39,6 +40,9 @@ def markdown_format_result(result: Result) -> str: patch_sets.append(patch_set) total_files_modified += len(patch_set.modified_files) + if comparison.diff: + projects_with_changes += 1 + if total_lines_removed == 0 and total_lines_added == 0 and error_count == 0: return "\u2705 ecosystem check detected no format changes." @@ -51,11 +55,21 @@ def markdown_format_result(result: Result) -> str: ) else: s = "s" if total_files_modified != 1 else "" - changes = f"+{total_lines_added} -{total_lines_removed} lines in {total_files_modified} file{s} in {len(result.completed)} projects" + changes = ( + f"+{total_lines_added} -{total_lines_removed} lines " + f"in {total_files_modified} file{s} in " + f"{projects_with_changes} projects" + ) + if error_count: s = "s" if error_count != 1 else "" changes += f"; {error_count} project error{s}" + unchanged_projects = len(result.completed) - projects_with_changes + if unchanged_projects: + s = "s" if unchanged_projects != 1 else "" + changes += f"; {unchanged_projects} project{s} unchanged" + lines.append( f"\u2139\ufe0f ecosystem check **detected format changes**. ({changes})" ) @@ -97,7 +111,7 @@ def format_patchset(patch_set: PatchSet, repo: ClonedRepository) -> str: """ Convert a patchset to markdown, adding permalinks to the start of each hunk. """ - lines = [] + lines: list[str] = [] for file_patch in patch_set: for hunk in file_patch: # Note: When used for `format` checks, the line number is not exact because diff --git a/python/ruff-ecosystem/ruff_ecosystem/main.py b/python/ruff-ecosystem/ruff_ecosystem/main.py index e7f50093b960a..ca0e3037c78b5 100644 --- a/python/ruff-ecosystem/ruff_ecosystem/main.py +++ b/python/ruff-ecosystem/ruff_ecosystem/main.py @@ -53,7 +53,7 @@ async def limited_parallelism(coroutine: Awaitable[T]) -> T: async with semaphore: return await coroutine - comparisons: list[Exception | Comparison] = await asyncio.gather( + comparisons: list[BaseException | Comparison] = await asyncio.gather( *[ limited_parallelism( clone_and_compare( @@ -72,9 +72,10 @@ async def limited_parallelism(coroutine: Awaitable[T]) -> T: comparisons_by_target = dict(zip(targets, comparisons, strict=True)) # Split comparisons into errored / completed - errored, completed = [], [] + errored: list[tuple[Project, BaseException]] = [] + completed: list[tuple[Project, Comparison]] = [] for target, comparison in comparisons_by_target.items(): - if isinstance(comparison, Exception): + if isinstance(comparison, BaseException): errored.append((target, comparison)) else: completed.append((target, comparison)) @@ -138,7 +139,7 @@ async def clone_and_compare( class JSONEncoder(json.JSONEncoder): - def default(self, o): + def default(self, o: object): if isinstance(o, Serializable): return o.jsonable() if dataclasses.is_dataclass(o): diff --git a/python/ruff-ecosystem/ruff_ecosystem/markdown.py b/python/ruff-ecosystem/ruff_ecosystem/markdown.py index e6f606069515e..0af3b20367971 100644 --- a/python/ruff-ecosystem/ruff_ecosystem/markdown.py +++ b/python/ruff-ecosystem/ruff_ecosystem/markdown.py @@ -3,11 +3,11 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from ruff_ecosystem.projects import Project + from ruff_ecosystem.projects import CommandOptions, Project def markdown_project_section( - title: str, content: str | list[str], options: object, project: Project + title: str, content: str | list[str], options: CommandOptions, project: Project ) -> list[str]: return markdown_details( summary=f'{project.repo.fullname} ({title})', @@ -28,8 +28,10 @@ def markdown_plus_minus(added: int, removed: int) -> str: return f"+{added} -{removed}" -def markdown_details(summary: str, content: str | list[str], preface: str): - lines = [] +def markdown_details( + summary: str, content: str | list[str], preface: str | None +) -> list[str]: + lines: list[str] = [] lines.append(f"
{summary}") if preface: lines.append("

") diff --git a/python/ruff-ecosystem/ruff_ecosystem/projects.py b/python/ruff-ecosystem/ruff_ecosystem/projects.py index d4764c34bf040..fa5f8224a8958 100644 --- a/python/ruff-ecosystem/ruff_ecosystem/projects.py +++ b/python/ruff-ecosystem/ruff_ecosystem/projects.py @@ -71,7 +71,12 @@ class CheckOptions(CommandOptions): max_lines_per_rule: int | None = 50 def to_ruff_args(self) -> list[str]: - args = ["check", "--no-cache", "--exit-zero"] + args = [ + "check", + "--no-cache", + "--exit-zero", + f"--{'' if self.preview else 'no-'}preview", + ] if self.select: args.extend(["--select", self.select]) if self.ignore: @@ -80,8 +85,6 @@ def to_ruff_args(self) -> list[str]: args.extend(["--exclude", self.exclude]) if self.show_fixes: args.extend(["--show-fixes", "--ecosystem-ci"]) - if self.preview: - args.append("--preview") return args @@ -95,15 +98,13 @@ class FormatOptions(CommandOptions): exclude: str = "" def to_ruff_args(self) -> list[str]: - args = ["format"] + args = ["format", f"--{'' if self.preview else 'no-'}preview"] if self.exclude: args.extend(["--exclude", self.exclude]) - if self.preview: - args.append("--preview") return args def to_black_args(self) -> list[str]: - args = [] + args: list[str] = [] if self.exclude: args.extend(["--exclude", self.exclude]) if self.preview: diff --git a/python/ruff-ecosystem/ruff_ecosystem/types.py b/python/ruff-ecosystem/ruff_ecosystem/types.py index 41a9b02aab310..e9b9664aeea44 100644 --- a/python/ruff-ecosystem/ruff_ecosystem/types.py +++ b/python/ruff-ecosystem/ruff_ecosystem/types.py @@ -32,11 +32,15 @@ def __init__(self, lines: Iterable[str], leading_spaces: int = 0) -> None: line[2:] for line in self.lines if line.startswith("+" + " " * leading_spaces) + # Do not include patch headers + and not line.startswith("+++") ) self.removed = list( line[2:] for line in self.lines if line.startswith("-" + " " * leading_spaces) + # Do not include patch headers + and not line.startswith("---") ) def __bool__(self) -> bool: @@ -75,7 +79,7 @@ class Result(Serializable): The result of an ecosystem check for a collection of projects. """ - errored: list[tuple[Project, Exception]] + errored: list[tuple[Project, BaseException]] completed: list[tuple[Project, Comparison]] diff --git a/ruff.schema.json b/ruff.schema.json index 2f8151f69fead..594058724a331 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -690,7 +690,7 @@ } }, "unsafe-fixes": { - "description": "Enable application of unsafe fixes.", + "description": "Enable application of unsafe fixes. If excluded, a hint will be displayed when unsafe fixes are available. If set to false, the hint will be hidden.", "type": [ "boolean", "null" @@ -747,6 +747,16 @@ } ] }, + "DocstringCodeLineWidth": { + "anyOf": [ + { + "$ref": "#/definitions/LineWidth" + }, + { + "type": "null" + } + ] + }, "Flake8AnnotationsOptions": { "type": "object", "properties": { @@ -1194,6 +1204,13 @@ "type": "string" } }, + "quote-annotations": { + "description": "Whether to add quotes around type annotations, if doing so would allow the corresponding import to be moved into a type-checking block.\n\nFor example, in the following, Python requires that `Sequence` be available at runtime, despite the fact that it's only used in a type annotation:\n\n```python from collections.abc import Sequence\n\ndef func(value: Sequence[int]) -> None: ... ```\n\nIn other words, moving `from collections.abc import Sequence` into an `if TYPE_CHECKING:` block above would cause a runtime error, as the type would no longer be available at runtime.\n\nBy default, Ruff will respect such runtime semantics and avoid moving the import to prevent such runtime errors.\n\nSetting `quote-annotations` to `true` will instruct Ruff to add quotes around the annotation (e.g., `\"Sequence[int]\"`), which in turn enables Ruff to move the import into an `if TYPE_CHECKING:` block, like so:\n\n```python from typing import TYPE_CHECKING\n\nif TYPE_CHECKING: from collections.abc import Sequence\n\ndef func(value: \"Sequence[int]\") -> None: ... ```\n\nNote that this setting has no effect when `from __future__ import annotations` is present, as `__future__` annotations are always treated equivalently to quoted annotations.", + "type": [ + "boolean", + "null" + ] + }, "runtime-evaluated-base-classes": { "description": "Exempt classes that list any of the enumerated classes as a base class from needing to be moved into type-checking blocks.\n\nCommon examples include Pydantic's `pydantic.BaseModel` and SQLAlchemy's `sqlalchemy.orm.DeclarativeBase`, but can also support user-defined classes that inherit from those base classes. For example, if you define a common `DeclarativeBase` subclass that's used throughout your project (e.g., `class Base(DeclarativeBase) ...` in `base.py`), you can add it to this list (`runtime-evaluated-base-classes = [\"base.Base\"]`) to exempt models from being moved into type-checking blocks.", "type": [ @@ -1241,6 +1258,24 @@ "description": "Experimental: Configures how `ruff format` formats your code.\n\nPlease provide feedback in [this discussion](https://github.com/astral-sh/ruff/discussions/7310).", "type": "object", "properties": { + "docstring-code-format": { + "description": "Whether to format code snippets in docstrings.\n\nWhen this is enabled, Python code examples within docstrings are automatically reformatted.\n\nFor example, when this is enabled, the following code:\n\n```python def f(x): \"\"\" Something about `f`. And an example in doctest format:\n\n>>> f( x )\n\nMarkdown is also supported:\n\n```py f( x ) ```\n\nAs are reStructuredText literal blocks::\n\nf( x )\n\nAnd reStructuredText code blocks:\n\n.. code-block:: python\n\nf( x ) \"\"\" pass ```\n\n... will be reformatted (assuming the rest of the options are set to their defaults) as:\n\n```python def f(x): \"\"\" Something about `f`. And an example in doctest format:\n\n>>> f(x)\n\nMarkdown is also supported:\n\n```py f(x) ```\n\nAs are reStructuredText literal blocks::\n\nf(x)\n\nAnd reStructuredText code blocks:\n\n.. code-block:: python\n\nf(x) \"\"\" pass ```\n\nIf a code snippt in a docstring contains invalid Python code or if the formatter would otherwise write invalid Python code, then the code example is ignored by the formatter and kept as-is.\n\nCurrently, doctest, Markdown, reStructuredText literal blocks, and reStructuredText code blocks are all supported and automatically recognized. In the case of unlabeled fenced code blocks in Markdown and reStructuredText literal blocks, the contents are assumed to be Python and reformatted. As with any other format, if the contents aren't valid Python, then the block is left untouched automatically.", + "type": [ + "boolean", + "null" + ] + }, + "docstring-code-line-length": { + "description": "Set the line length used when formatting code snippets in docstrings.\n\nThis only has an effect when the `docstring-code-format` setting is enabled.\n\nThe default value for this setting is `\"dynamic\"`, which has the effect of ensuring that any reformatted code examples in docstrings adhere to the global line length configuration that is used for the surrounding Python code. The point of this setting is that it takes the indentation of the docstring into account when reformatting code examples.\n\nAlternatively, this can be set to a fixed integer, which will result in the same line length limit being applied to all reformatted code examples in docstrings. When set to a fixed integer, the indent of the docstring is not taken into account. That is, this may result in lines in the reformatted code example that exceed the globally configured line length limit.\n\nFor example, when this is set to `20` and `docstring-code-format` is enabled, then this code:\n\n```python def f(x): ''' Something about `f`. And an example:\n\n.. code-block:: python\n\nfoo, bar, quux = this_is_a_long_line(lion, hippo, lemur, bear) ''' pass ```\n\n... will be reformatted (assuming the rest of the options are set to their defaults) as:\n\n```python def f(x): \"\"\" Something about `f`. And an example:\n\n.. code-block:: python\n\n( foo, bar, quux, ) = this_is_a_long_line( lion, hippo, lemur, bear, ) \"\"\" pass ```", + "anyOf": [ + { + "$ref": "#/definitions/DocstringCodeLineWidth" + }, + { + "type": "null" + } + ] + }, "exclude": { "description": "A list of file patterns to exclude from formatting in addition to the files excluded globally (see [`exclude`](#exclude), and [`extend-exclude`](#extend-exclude)).\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", "type": [ @@ -1281,7 +1316,7 @@ ] }, "quote-style": { - "description": "Whether to prefer single `'` or double `\"` quotes for strings. Defaults to double quotes.\n\nIn compliance with [PEP 8](https://peps.python.org/pep-0008/) and [PEP 257](https://peps.python.org/pep-0257/), Ruff prefers double quotes for multiline strings and docstrings, regardless of the configured quote style.\n\nRuff may also deviate from this option if using the configured quotes would require escaping quote characters within the string. For example, given:\n\n```python a = \"a string without any quotes\" b = \"It's monday morning\" ```\n\nRuff will change `a` to use single quotes when using `quote-style = \"single\"`. However, `b` will be unchanged, as converting to single quotes would require the inner `'` to be escaped, which leads to less readable code: `'It\\'s monday morning'`.", + "description": "Configures the preferred quote character for strings. Valid options are:\n\n* `double` (default): Use double quotes `\"` * `single`: Use single quotes `'` * `preserve` (preview only): Keeps the existing quote character. We don't recommend using this option except for projects that already use a mixture of single and double quotes and can't migrate to using double or single quotes.\n\nIn compliance with [PEP 8](https://peps.python.org/pep-0008/) and [PEP 257](https://peps.python.org/pep-0257/), Ruff prefers double quotes for multiline strings and docstrings, regardless of the configured quote style.\n\nRuff may also deviate from using the configured quotes if doing so requires escaping quote characters within the string. For example, given:\n\n```python a = \"a string without any quotes\" b = \"It's monday morning\" ```\n\nRuff will change `a` to use single quotes when using `quote-style = \"single\"`. However, `b` remains unchanged, as converting to single quotes requires escaping the inner `'`, which leads to less readable code: `'It\\'s monday morning'`. This does not apply when using `preserve`.", "anyOf": [ { "$ref": "#/definitions/QuoteStyle" @@ -1440,6 +1475,13 @@ "type": "string" } }, + "from-first": { + "description": "Whether to place `import from` imports before straight imports when sorting.\n\nFor example, by default, imports will be sorted such that straight imports appear before `import from` imports, as in: ```python import os import sys from typing import List ```\n\nSetting `from-first = true` will instead sort such that `import from` imports appear before straight imports, as in: ```python from typing import List import os import sys ```", + "type": [ + "boolean", + "null" + ] + }, "known-first-party": { "description": "A list of modules to consider first-party, regardless of whether they can be identified as such via introspection of the local filesystem.\n\nSupports glob patterns. For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", "type": [ @@ -1470,6 +1512,20 @@ "type": "string" } }, + "length-sort": { + "description": "Sort imports by their string length, such that shorter imports appear before longer imports. For example, by default, imports will be sorted alphabetically, as in: ```python import collections import os ```\n\nSetting `length-sort = true` will instead sort such that shorter imports appear before longer imports, as in: ```python import os import collections ```", + "type": [ + "boolean", + "null" + ] + }, + "length-sort-straight": { + "description": "Sort straight imports by their string length. Similar to `length-sort`, but applies only to straight imports and doesn't affect `from` imports.", + "type": [ + "boolean", + "null" + ] + }, "lines-after-imports": { "description": "The number of blank lines to place after imports. Use `-1` for automatic determination.\n\nWhen using the formatter, only the values `-1`, `1`, and `2` are compatible because it enforces at least one empty and at most two empty lines after imports.", "type": [ @@ -1624,6 +1680,12 @@ "maximum": 320.0, "minimum": 1.0 }, + "LineWidth": { + "description": "The maximum visual width to which the formatter should try to limit a line.", + "type": "integer", + "format": "uint16", + "minimum": 1.0 + }, "LintOptions": { "description": "Experimental section to configure Ruff's linting. This new section will eventually replace the top-level linting options.\n\nOptions specified in the `lint` section take precedence over the top-level settings.", "type": "object", @@ -2300,6 +2362,17 @@ "PylintOptions": { "type": "object", "properties": { + "allow-dunder-method-names": { + "description": "Dunder methods name to allow, in addition to the default set from the Python standard library (see: `PLW3201`).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + }, "allow-magic-value-types": { "description": "Constant types to ignore when used as \"magic values\" (see: `PLR2004`).", "type": [ @@ -2337,6 +2410,15 @@ "format": "uint", "minimum": 0.0 }, + "max-positional-args": { + "description": "Maximum number of positional arguments allowed for a function or method definition (see: `PLR0917`).\n\nIf not specified, defaults to the value of `max-args`.", + "type": [ + "integer", + "null" + ], + "format": "uint", + "minimum": 0.0 + }, "max-public-methods": { "description": "Maximum number of public methods allowed for a class (see: `PLR0904`).", "type": [ @@ -2400,7 +2482,8 @@ "type": "string", "enum": [ "single", - "double" + "double", + "preserve" ] }, "RelativeImportsOrder": { @@ -2839,11 +2922,14 @@ "FURB15", "FURB152", "FURB16", + "FURB163", "FURB168", "FURB169", "FURB17", "FURB171", "FURB177", + "FURB18", + "FURB181", "G", "G0", "G00", @@ -3077,6 +3163,8 @@ "PLR0133", "PLR02", "PLR020", + "PLR0202", + "PLR0203", "PLR0206", "PLR04", "PLR040", @@ -3090,6 +3178,7 @@ "PLR0913", "PLR0915", "PLR0916", + "PLR0917", "PLR1", "PLR17", "PLR170", @@ -3101,6 +3190,9 @@ "PLR1714", "PLR172", "PLR1722", + "PLR173", + "PLR1733", + "PLR1736", "PLR2", "PLR20", "PLR200", @@ -3358,6 +3450,7 @@ "S2", "S20", "S201", + "S202", "S3", "S30", "S301", @@ -3404,6 +3497,7 @@ "S608", "S609", "S61", + "S611", "S612", "S7", "S70", @@ -3611,7 +3705,8 @@ "github", "gitlab", "pylint", - "azure" + "azure", + "sarif" ] }, "Strictness": { diff --git a/scripts/benchmarks/pyproject.toml b/scripts/benchmarks/pyproject.toml index fedde2ac9d22a..c7b4070e1a19a 100644 --- a/scripts/benchmarks/pyproject.toml +++ b/scripts/benchmarks/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "scripts" -version = "0.1.6" +version = "0.1.8" description = "" authors = ["Charles Marsh "] diff --git a/scripts/formatter_ecosystem_checks.sh b/scripts/formatter_ecosystem_checks.sh index 7acf0974a1cec..349e82077c2f5 100755 --- a/scripts/formatter_ecosystem_checks.sh +++ b/scripts/formatter_ecosystem_checks.sh @@ -67,7 +67,7 @@ git -C "$dir/home-assistant" checkout -q 88296c1998fd1943576e0167ab190d25af17525 if [ ! -d "$dir/poetry/.git" ]; then git clone --filter=tree:0 https://github.com/python-poetry/poetry "$dir/poetry" fi -git -C "$dir/poetry" checkout -q f5cb9f0fb19063cf280faf5e39c82d5691da9939 +git -C "$dir/poetry" checkout -q f310a592ad3ab41bb8d635af6bacaf044a1fefef # cpython itself if [ ! -d "$dir/cpython/.git" ]; then @@ -75,12 +75,6 @@ if [ ! -d "$dir/cpython/.git" ]; then fi git -C "$dir/cpython" checkout -q b75186f69edcf54615910a5cd707996144163ef7 -# poetry itself -if [ ! -d "$dir/poetry/.git" ]; then - git clone --filter=tree:0 https://github.com/python-poetry/poetry "$dir/poetry" -fi -git -C "$dir/poetry" checkout -q 611033a7335f3c8e2b74dd58688fb9021cf84a5b - # Uncomment if you want to update the hashes #for i in "$dir"/*/; do git -C "$i" switch main && git -C "$i" pull; done #for i in "$dir"/*/; do echo "# $(basename "$i") $(git -C "$i" rev-parse HEAD)"; done