Compare commits

...

19 Commits

Author SHA1 Message Date
Jeong, YunWon
39a6486a4c Release v0.5.0 2026-03-31 21:06:00 +09:00
Jeong, YunWon
d9c4c95369 fix crates (#7549) 2026-03-31 21:05:08 +09:00
Jeong, YunWon
403c2be01d Improve codegen bytecode parity (#7541)
- Add CFG block splitting, jump threading, backward jump normalization
- Add genexpr StopIteration wrapper
- Add ConstantData::Slice and constant slice folding
- Add duplicate_exits_without_lineno and Block: Clone
- Add builtin(genexpr) optimization for tuple/list/set/all/any
- Add compile_try_except_no_finally for try-except without finally
- Add module_name_declared_global_in_nested_scope
- Add constant tuple folding in try_fold_constant_expr
- Add fstring literal-only optimization and empty literal elision
- Fix duplicate_exits_without_lineno: splice new blocks into linked list
2026-03-31 15:45:18 +09:00
Shahar Naveh
5cc9eab2dd Resolve excessive-permissions warning in ci.yaml (#7547)
* Resolve `excessive-permissions` warning in `ci.yaml`

* Update .github/workflows/ci.yaml

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-31 14:53:08 +09:00
dependabot[bot]
b275a90cf9 Bump j178/prek-action from 2.0.0 to 2.0.1 (#7544)
Bumps [j178/prek-action](https://github.com/j178/prek-action) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/j178/prek-action/releases)
- [Commits](79f765515b...53276d8b0d)

---
updated-dependencies:
- dependency-name: j178/prek-action
  dependency-version: 2.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 18:38:01 +02:00
dependabot[bot]
43851c21b9 Bump minimatch and serve in /wasm/demo (#7539)
Bumps [minimatch](https://github.com/isaacs/minimatch) to 3.1.5 and updates ancestor dependency [serve](https://github.com/vercel/serve). These dependencies need to be updated together.


Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5)

Updates `serve` from 14.2.5 to 14.2.6
- [Release notes](https://github.com/vercel/serve/releases)
- [Changelog](https://github.com/vercel/serve/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vercel/serve/compare/v14.2.5...v14.2.6)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
- dependency-name: serve
  dependency-version: 14.2.6
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-31 01:31:08 +09:00
Shahar Naveh
611b122ed7 Resolve template injection (#7546) 2026-03-31 01:30:41 +09:00
dependabot[bot]
1a4964b741 Bump dtolnay/rust-toolchain (#7545)
Bumps [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from efa25f7f19611383d5b0ccf2d1c8914531636bf9 to 3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9.
- [Release notes](https://github.com/dtolnay/rust-toolchain/releases)
- [Commits](efa25f7f19...3c5f7ea28c)

---
updated-dependencies:
- dependency-name: dtolnay/rust-toolchain
  dependency-version: 3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-31 01:30:08 +09:00
dependabot[bot]
106f1c9f37 Bump env_logger from 0.11.9 to 0.11.10 (#7543)
Bumps [env_logger](https://github.com/rust-cli/env_logger) from 0.11.9 to 0.11.10.
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/v0.11.9...v0.11.10)

---
updated-dependencies:
- dependency-name: env_logger
  dependency-version: 0.11.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-31 01:29:47 +09:00
dependabot[bot]
c45f69977b Bump schannel from 0.1.28 to 0.1.29 (#7542)
Bumps [schannel](https://github.com/steffengy/schannel-rs) from 0.1.28 to 0.1.29.
- [Release notes](https://github.com/steffengy/schannel-rs/releases)
- [Commits](https://github.com/steffengy/schannel-rs/compare/v0.1.28...v0.1.29)

---
updated-dependencies:
- dependency-name: schannel
  dependency-version: 0.1.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-31 01:29:35 +09:00
Shahar Naveh
2703f94c3e Split cargo check matrix to individual targets. Avoid cache poisoning (#7540)
* Split check matrix. Prevent cache poisoning

* Use `rustup`

* Change name

* Align cargo args
2026-03-30 23:59:48 +09:00
Shahar Naveh
9900c761ca Fix lint warnings in release.yml (#7538) 2026-03-30 18:53:38 +09:00
Shahar Naveh
959b088d25 Remove oparg builders (#7537) 2026-03-30 18:53:13 +09:00
Jeong, YunWon
1c39fdb7f9 Bytecode parity (#7536)
* Add CFG block splitting, jump threading, backward jump normalization, genexpr StopIteration wrapper

- split_blocks_at_jumps: split blocks at branch points so each has one exit
- jump_threading: thread jumps through single-jump blocks (flowgraph.c jump_thread)
- Backward conditional jump normalization: invert and create NOT_TAKEN+JUMP block
- Follow empty blocks in jump-to-return optimization (next_nonempty_block)
- Add PEP 479 StopIteration handler to compile_comprehension for generators

* Add ConstantData::Slice and constant slice folding

- Add Slice variant to ConstantData and BorrowedConstant
- Fold constant slices (x[:3], x[1:4]) into LOAD_CONST(slice(...))
- Marshal serialization/deserialization for Slice type
- Box::leak in borrow_obj_constant for PySlice roundtrip

* Add duplicate_exits_without_lineno (disabled) and Block: Clone

Prepare infrastructure for exit block duplication optimization.
Currently disabled pending stackdepth integration.

* Improve codegen bytecode parity
2026-03-30 18:50:58 +09:00
Jeong, YunWon
3706c5376e Bytecode parity (#7535)
* Add CFG block splitting, jump threading, backward jump normalization, genexpr StopIteration wrapper

- split_blocks_at_jumps: split blocks at branch points so each has one exit
- jump_threading: thread jumps through single-jump blocks (flowgraph.c jump_thread)
- Backward conditional jump normalization: invert and create NOT_TAKEN+JUMP block
- Follow empty blocks in jump-to-return optimization (next_nonempty_block)
- Add PEP 479 StopIteration handler to compile_comprehension for generators

* Add ConstantData::Slice and constant slice folding

- Add Slice variant to ConstantData and BorrowedConstant
- Fold constant slices (x[:3], x[1:4]) into LOAD_CONST(slice(...))
- Marshal serialization/deserialization for Slice type
- Box::leak in borrow_obj_constant for PySlice roundtrip

* Add ConstantData::Frozenset variant (type only, folding deferred)

Add Frozenset to ConstantData, BorrowedConstant, and marshal support.
Actual frozenset folding (BUILD_SET + CONTAINS_OP → LOAD_CONST frozenset)
requires VirtualMachine for element hashing and is deferred.

* Add duplicate_exits_without_lineno (disabled) and Block: Clone

Prepare infrastructure for exit block duplication optimization.
Currently disabled pending stackdepth integration.
2026-03-30 12:52:04 +09:00
Huy VĹ© (Josh)
e6bcd64066 Validate SyntaxError details tuple shape (#7533) 2026-03-29 22:37:08 +09:00
Jeong, YunWon
2ebd7026e4 Compiler parity: docstring dedent, StopIteration wrapper, constant folding (#7530) 2026-03-29 22:36:20 +09:00
Jeong, YunWon
6826557884 ruff from fork (#7532) 2026-03-29 19:26:24 +09:00
Jeong, YunWon
1f6b4c6bf1 ruff 0.15.8 (#7531) 2026-03-29 15:21:09 +09:00
33 changed files with 3412 additions and 788 deletions

View File

@@ -8,6 +8,9 @@ on:
name: CI
permissions:
contents: read
# Cancel previous workflows if they are the same workflow on same ref (branch/tags)
# with the same event (push/pull_request) even they are in progress.
# This setting will help reduce the number of duplicated workflows.
@@ -27,6 +30,8 @@ env:
PYTHON_VERSION: "3.14.3"
X86_64_PC_WINDOWS_MSVC_OPENSSL_LIB_DIR: C:\Program Files\OpenSSL\lib\VC\x64\MD
X86_64_PC_WINDOWS_MSVC_OPENSSL_INCLUDE_DIR: C:\Program Files\OpenSSL\include
CARGO_INCREMENTAL: 0
CARGO_TERM_COLOR: always
jobs:
rust_tests:
@@ -45,7 +50,7 @@ jobs:
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
with:
components: clippy
toolchain: stable
@@ -108,41 +113,39 @@ jobs:
cargo_check:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
name: Ensure compilation on various targets
name: cargo check
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
targets:
- aarch64-linux-android
- i686-unknown-linux-gnu
- i686-unknown-linux-musl
- wasm32-wasip2
- x86_64-unknown-freebsd
target: aarch64-linux-android
- os: ubuntu-latest
target: i686-unknown-linux-gnu
dependencies:
gcc-multilib: true
- os: ubuntu-latest
target: i686-unknown-linux-musl
dependencies:
musl-tools: true
- os: ubuntu-latest
targets:
- aarch64-unknown-linux-gnu
target: wasm32-wasip2
- os: ubuntu-latest
target: x86_64-unknown-freebsd
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
dependencies:
gcc-aarch64-linux-gnu: true # conflict with `gcc-multilib`
gcc-aarch64-linux-gnu: true
- os: macos-latest
targets:
- aarch64-apple-ios
- x86_64-apple-darwin
target: aarch64-apple-ios
- os: macos-latest
target: x86_64-apple-darwin
fail-fast: false
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
prefix-key: v0-rust-${{ join(matrix.targets, '-') }}
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install dependencies
uses: ./.github/actions/install-linux-deps
# zizmor has an issue with dynamic `with`
@@ -152,13 +155,25 @@ jobs:
musl-tools: ${{ matrix.dependencies.musl-tools || false }}
gcc-aarch64-linux-gnu: ${{ matrix.dependencies.gcc-aarch64-linux-gnu || false }}
- uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
- name: Restore cache
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
if: ${{ github.ref != 'refs/heads/main' }} # Never restore on main
with:
targets: ${{ join(matrix.targets, ',') }}
toolchain: stable
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
# key won't match, will rely on restore-keys
key: cargo-check-${{ runner.os }}-${{ matrix.target }}
restore-keys: |
cargo-check-${{ runner.os }}-${{ matrix.target }}-
- run: rustup toolchain install stable --target "${{ matrix.target }}"
- name: Setup Android NDK
if: ${{ contains(matrix.targets, 'aarch64-linux-android') }}
if: ${{ matrix.target == 'aarch64-linux-android' }}
id: setup-ndk
uses: nttld/setup-ndk@v1
with:
@@ -174,18 +189,24 @@ jobs:
# args: --ignore-rust-version
- name: Check compilation
run: |
for target in ${{ join(matrix.targets, ' ') }}
do
echo "::group::${target}"
cargo check --target $target ${{ env.CARGO_ARGS_NO_SSL }}
echo "::endgroup::"
done
run: cargo check --target "${{ matrix.target }}" ${{ env.CARGO_ARGS_NO_SSL }}
env:
CC_aarch64_linux_android: ${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang
AR_aarch64_linux_android: ${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: ${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang
- name: Save cache
if: ${{ github.ref == 'refs/heads/main' }} # only save on main
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: cargo-check-${{ runner.os }}-${{ matrix.target }}-${{ hashFiles('**/Cargo.toml') }}-${{ hashFiles('Cargo.lock') }}-${{ github.sha }}
snippets_cpython:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
env:
@@ -230,7 +251,7 @@ jobs:
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
with:
toolchain: stable
@@ -345,7 +366,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}
- uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
with:
toolchain: stable
components: rustfmt
@@ -372,7 +393,7 @@ jobs:
- name: prek
id: prek
uses: j178/prek-action@79f765515bd648eb4d6bb1b17277b7cb22cb6468 # v2.0.0
uses: j178/prek-action@53276d8b0d10f8b6672aa85b4588c6921d0370cc # v2.0.1
with:
cache: false
show-verbose-logs: false
@@ -404,7 +425,7 @@ jobs:
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
with:
toolchain: ${{ env.NIGHTLY_CHANNEL }}
components: miri
@@ -430,7 +451,7 @@ jobs:
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
with:
components: clippy
toolchain: stable
@@ -508,7 +529,7 @@ jobs:
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
with:
target: wasm32-wasip1
toolchain: stable

View File

@@ -18,4 +18,6 @@ jobs:
steps:
# Using REST API and not `gh issue edit`. https://github.com/cli/cli/issues/6235#issuecomment-1243487651
- run: |
curl -H "Authorization: token ${{ github.token }}" -d '{"assignees": ["${{ github.event.comment.user.login }}"]}' https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees
curl -H "Authorization: token ${{ github.token }}" -d '{"assignees": ["${{ env.USER }}"]}' https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees
env:
USER: ${{ github.event.comment.user.login }}

View File

@@ -12,9 +12,6 @@ on:
required: false
default: true
permissions:
contents: write
env:
X86_64_PC_WINDOWS_MSVC_OPENSSL_LIB_DIR: C:\Program Files\OpenSSL\lib\VC\x64\MD
X86_64_PC_WINDOWS_MSVC_OPENSSL_INCLUDE_DIR: C:\Program Files\OpenSSL\include
@@ -55,7 +52,7 @@ jobs:
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
with:
target: ${{ matrix.target }}
@@ -92,7 +89,7 @@ jobs:
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
with:
targets: wasm32-wasip1
@@ -115,8 +112,9 @@ jobs:
with:
package-manager-cache: false
- uses: mwilliamson/setup-wabt-action@v3
with: { wabt-version: "1.0.30" }
- uses: mwilliamson/setup-wabt-action@febe2a12b7ccb999a6e5d953a8362a3b7ffcf148 # v3.2.0
with:
wabt-version: "1.0.30"
- name: build demo
run: |
@@ -137,7 +135,7 @@ jobs:
- name: Deploy demo to Github Pages
if: ${{ github.repository == 'RustPython/RustPython' }}
uses: peaceiris/actions-gh-pages@v4
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with:
deploy_key: ${{ secrets.ACTIONS_DEMO_DEPLOY_KEY }}
publish_dir: ./wasm/demo/dist

357
Cargo.lock generated
View File

@@ -79,9 +79,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstream"
version = "0.6.21"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -100,9 +100,9 @@ checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
"utf8parse",
]
@@ -187,7 +187,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
"synstructure",
]
@@ -199,7 +199,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -222,7 +222,7 @@ dependencies = [
"manyhow",
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -238,7 +238,7 @@ dependencies = [
"proc-macro2",
"quote",
"quote-use",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -299,22 +299,22 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
[[package]]
name = "bindgen"
version = "0.71.1"
version = "0.64.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"
dependencies = [
"bitflags 2.11.0",
"bitflags 1.3.2",
"cexpr",
"clang-sys",
"itertools 0.13.0",
"log",
"prettyplease",
"lazy_static 1.5.0",
"lazycell",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"rustc-hash 1.1.0",
"shlex",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -332,9 +332,9 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"rustc-hash 2.1.1",
"shlex",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -778,7 +778,7 @@ dependencies = [
"libm",
"log",
"regalloc2",
"rustc-hash",
"rustc-hash 2.1.1",
"serde",
"smallvec",
"target-lexicon",
@@ -1023,7 +1023,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -1043,7 +1043,7 @@ checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -1086,7 +1086,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -1143,9 +1143,9 @@ dependencies = [
[[package]]
name = "env_logger"
version = "0.11.9"
version = "0.11.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d"
checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a"
dependencies = [
"anstream",
"anstyle",
@@ -1232,7 +1232,7 @@ checksum = "7693d9dd1ec1c54f52195dfe255b627f7cec7da33b679cd56de949e662b3db10"
dependencies = [
"flame",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -1333,7 +1333,7 @@ checksum = "f2b6d1e2f75c16bfbcd0f95d84f99858a6e2f885c2287d1f5c3a96e8444a34b4"
dependencies = [
"attribute-derive",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -1550,7 +1550,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -1585,9 +1585,9 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "jiff"
version = "0.2.18"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e67e8da4c49d6d9909fe03361f9b620f58898859f5c7aded68351e85e71ecf50"
checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359"
dependencies = [
"jiff-static",
"log",
@@ -1598,13 +1598,13 @@ dependencies = [
[[package]]
name = "jiff-static"
version = "0.2.18"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78"
checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -1680,6 +1680,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lexical-parse-float"
version = "1.0.6"
@@ -1924,7 +1930,7 @@ dependencies = [
"manyhow-macros",
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2125,7 +2131,7 @@ checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2187,7 +2193,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2256,7 +2262,8 @@ dependencies = [
[[package]]
name = "parking_lot_core"
version = "0.9.12"
source = "git+https://github.com/youknowone/parking_lot?branch=rustpython#4392edbe879acc9c0dd94eda53d2205d3ab912c9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
dependencies = [
"cfg-if",
"libc",
@@ -2281,6 +2288,12 @@ dependencies = [
"hmac",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
@@ -2359,7 +2372,7 @@ dependencies = [
"phf_shared 0.13.1",
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2461,7 +2474,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2501,7 +2514,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2590,7 +2603,7 @@ dependencies = [
"proc-macro2",
"pyo3-macros-backend",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2603,7 +2616,7 @@ dependencies = [
"proc-macro2",
"pyo3-build-config",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2634,7 +2647,7 @@ dependencies = [
"proc-macro-utils",
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2784,7 +2797,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2797,7 +2810,7 @@ dependencies = [
"bumpalo",
"hashbrown 0.15.5",
"log",
"rustc-hash",
"rustc-hash 2.1.1",
"smallvec",
]
@@ -2860,7 +2873,7 @@ dependencies = [
"pmutil",
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -2878,70 +2891,10 @@ dependencies = [
]
[[package]]
name = "ruff_python_ast"
version = "0.0.0"
source = "git+https://github.com/astral-sh/ruff.git?rev=e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675#e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675"
dependencies = [
"aho-corasick",
"bitflags 2.11.0",
"compact_str",
"get-size2",
"is-macro",
"memchr",
"ruff_python_trivia",
"ruff_source_file",
"ruff_text_size",
"rustc-hash",
"thiserror 2.0.18",
]
[[package]]
name = "ruff_python_parser"
version = "0.0.0"
source = "git+https://github.com/astral-sh/ruff.git?rev=e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675#e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675"
dependencies = [
"bitflags 2.11.0",
"bstr",
"compact_str",
"get-size2",
"memchr",
"ruff_python_ast",
"ruff_python_trivia",
"ruff_text_size",
"rustc-hash",
"static_assertions",
"unicode-ident",
"unicode-normalization",
"unicode_names2 1.3.0",
]
[[package]]
name = "ruff_python_trivia"
version = "0.0.0"
source = "git+https://github.com/astral-sh/ruff.git?rev=e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675#e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675"
dependencies = [
"itertools 0.14.0",
"ruff_source_file",
"ruff_text_size",
"unicode-ident",
]
[[package]]
name = "ruff_source_file"
version = "0.0.0"
source = "git+https://github.com/astral-sh/ruff.git?rev=e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675#e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675"
dependencies = [
"memchr",
"ruff_text_size",
]
[[package]]
name = "ruff_text_size"
version = "0.0.0"
source = "git+https://github.com/astral-sh/ruff.git?rev=e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675#e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675"
dependencies = [
"get-size2",
]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc-hash"
@@ -3068,9 +3021,9 @@ dependencies = [
"libc",
"log",
"pyo3",
"ruff_python_parser",
"rustpython-compiler",
"rustpython-pylib",
"rustpython-ruff_python_parser",
"rustpython-stdlib",
"rustpython-vm",
"rustyline",
@@ -3091,11 +3044,11 @@ dependencies = [
"memchr",
"num-complex",
"num-traits",
"ruff_python_ast",
"ruff_python_parser",
"ruff_text_size",
"rustpython-compiler-core",
"rustpython-literal",
"rustpython-ruff_python_ast",
"rustpython-ruff_python_parser",
"rustpython-ruff_text_size",
"rustpython-wtf8",
"thiserror 2.0.18",
"unicode_names2 2.0.0",
@@ -3132,12 +3085,12 @@ dependencies = [
name = "rustpython-compiler"
version = "0.5.0"
dependencies = [
"ruff_python_ast",
"ruff_python_parser",
"ruff_source_file",
"ruff_text_size",
"rustpython-codegen",
"rustpython-compiler-core",
"rustpython-ruff_python_ast",
"rustpython-ruff_python_parser",
"rustpython-ruff_source_file",
"rustpython-ruff_text_size",
"thiserror 2.0.18",
]
@@ -3151,16 +3104,16 @@ dependencies = [
"lz4_flex",
"malachite-bigint",
"num-complex",
"ruff_source_file",
"rustpython-ruff_source_file",
"rustpython-wtf8",
]
[[package]]
name = "rustpython-compiler-source"
version = "0.5.0+deprecated"
version = "0.4.1+deprecated"
dependencies = [
"ruff_source_file",
"ruff_text_size",
"rustpython-ruff_source_file",
"rustpython-ruff_text_size",
]
[[package]]
@@ -3169,7 +3122,7 @@ version = "0.5.0"
dependencies = [
"rustpython-compiler",
"rustpython-derive-impl",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -3182,7 +3135,7 @@ dependencies = [
"quote",
"rustpython-compiler-core",
"rustpython-doc",
"syn",
"syn 2.0.117",
"syn-ext",
"textwrap",
]
@@ -3232,6 +3185,77 @@ dependencies = [
"rustpython-derive",
]
[[package]]
name = "rustpython-ruff_python_ast"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f021ff72cabf5e2cd6d8ec8813d376a8445a228dc610ab56c27bd9054cda70d4"
dependencies = [
"aho-corasick",
"bitflags 2.11.0",
"compact_str",
"get-size2",
"is-macro",
"memchr",
"rustc-hash 2.1.1",
"rustpython-ruff_python_trivia",
"rustpython-ruff_source_file",
"rustpython-ruff_text_size",
"thiserror 2.0.18",
]
[[package]]
name = "rustpython-ruff_python_parser"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01e6ee78bd9671fb5766664b2695fe1f2a92a961f4d9101646c570d8acdb1e0b"
dependencies = [
"bitflags 2.11.0",
"bstr",
"compact_str",
"get-size2",
"memchr",
"rustc-hash 2.1.1",
"rustpython-ruff_python_ast",
"rustpython-ruff_python_trivia",
"rustpython-ruff_text_size",
"static_assertions",
"unicode-ident",
"unicode-normalization",
"unicode_names2 1.3.0",
]
[[package]]
name = "rustpython-ruff_python_trivia"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79e7cfd1056f3a02ff0d2d0e4474286ca963260782f878b7b81c1dd87432e682"
dependencies = [
"itertools 0.14.0",
"rustpython-ruff_source_file",
"rustpython-ruff_text_size",
"unicode-ident",
]
[[package]]
name = "rustpython-ruff_source_file"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "948107aad62ddb12a11fc7bf68a49e52a0b0a3737d415a2505e54f5a9edac737"
dependencies = [
"memchr",
"rustpython-ruff_text_size",
]
[[package]]
name = "rustpython-ruff_text_size"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8291ee0f5a779e54ccd4e0151a0c426f8b49a123f99b5b6545db17ccdd4277aa"
dependencies = [
"get-size2",
]
[[package]]
name = "rustpython-sre_engine"
version = "0.5.0"
@@ -3300,10 +3324,6 @@ dependencies = [
"pkcs8",
"pymath",
"rand_core 0.9.5",
"ruff_python_ast",
"ruff_python_parser",
"ruff_source_file",
"ruff_text_size",
"rustix",
"rustls",
"rustls-native-certs",
@@ -3311,6 +3331,10 @@ dependencies = [
"rustls-platform-verifier",
"rustpython-common",
"rustpython-derive",
"rustpython-ruff_python_ast",
"rustpython-ruff_python_parser",
"rustpython-ruff_source_file",
"rustpython-ruff_text_size",
"rustpython-vm",
"schannel",
"sha-1",
@@ -3384,9 +3408,6 @@ dependencies = [
"paste",
"psm",
"result-like",
"ruff_python_ast",
"ruff_python_parser",
"ruff_text_size",
"rustix",
"rustpython-codegen",
"rustpython-common",
@@ -3395,6 +3416,9 @@ dependencies = [
"rustpython-derive",
"rustpython-jit",
"rustpython-literal",
"rustpython-ruff_python_ast",
"rustpython-ruff_python_parser",
"rustpython-ruff_text_size",
"rustpython-sre_engine",
"rustyline",
"scoped-tls",
@@ -3506,9 +3530,9 @@ dependencies = [
[[package]]
name = "schannel"
version = "0.1.28"
version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939"
dependencies = [
"windows-sys 0.61.2",
]
@@ -3597,7 +3621,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -3665,14 +3689,6 @@ dependencies = [
"keccak",
]
[[package]]
name = "shared-build"
version = "0.2.0"
source = "git+https://github.com/arihant2math/tkinter.git?tag=v0.2.0#198fc35b1f18f4eda401f97a641908f321b1403a"
dependencies = [
"bindgen 0.71.1",
]
[[package]]
name = "shlex"
version = "1.3.0"
@@ -3765,7 +3781,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -3774,6 +3790,17 @@ version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.117"
@@ -3793,7 +3820,7 @@ checksum = "b126de4ef6c2a628a68609dd00733766c3b015894698a438ebdf374933fc31d1"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -3804,7 +3831,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -3837,10 +3864,14 @@ checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba"
[[package]]
name = "tcl-sys"
version = "0.2.0"
source = "git+https://github.com/arihant2math/tkinter.git?tag=v0.2.0#198fc35b1f18f4eda401f97a641908f321b1403a"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "081cd46ee0f9c78ab8ab54953239f7a2202f3efe1743e726b7b177d64c766cc0"
dependencies = [
"anyhow",
"bindgen 0.64.0",
"jobserver",
"libc",
"pkg-config",
"shared-build",
]
[[package]]
@@ -3897,7 +3928,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -3908,7 +3939,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -3987,10 +4018,14 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tk-sys"
version = "0.2.0"
source = "git+https://github.com/arihant2math/tkinter.git?tag=v0.2.0#198fc35b1f18f4eda401f97a641908f321b1403a"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "963faa16744bacdab52b5a4ab049e264b020f20f73bdf0b5cfbfa8b9a8a8f8b7"
dependencies = [
"bindgen 0.64.0",
"libc",
"pkg-config",
"shared-build",
"tcl-sys",
"x11",
]
[[package]]
@@ -4011,7 +4046,7 @@ checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -4378,7 +4413,7 @@ dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
"wasm-bindgen-shared",
]
@@ -4518,7 +4553,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -4529,7 +4564,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -4809,6 +4844,16 @@ version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
[[package]]
name = "x11"
version = "2.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e"
dependencies = [
"libc",
"pkg-config",
]
[[package]]
name = "x509-cert"
version = "0.2.5"
@@ -4863,7 +4908,7 @@ checksum = "d8187381b52e32220d50b255276aa16a084ec0a9017a0ca2152a1f55c539758d"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]
@@ -4883,7 +4928,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.117",
]
[[package]]

View File

@@ -101,7 +101,7 @@ opt-level = 3
lto = "thin"
[patch.crates-io]
parking_lot_core = { git = "https://github.com/youknowone/parking_lot", branch = "rustpython" }
# parking_lot_core = { git = "https://github.com/youknowone/parking_lot", branch = "rustpython" }
# REDOX START, Uncomment when you want to compile/check with redoxer
# REDOX END
@@ -156,12 +156,19 @@ rustpython-sre_engine = { path = "crates/sre_engine", version = "0.5.0" }
rustpython-wtf8 = { path = "crates/wtf8", version = "0.5.0" }
rustpython-doc = { path = "crates/doc", version = "0.5.0" }
# Ruff tag 0.15.6 is based on commit e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675
# Use RustPython-packaged Ruff crates from the published fork while keeping
# existing crate names in the codebase.
ruff_python_parser = { package = "rustpython-ruff_python_parser", version = "0.15.8" }
ruff_python_ast = { package = "rustpython-ruff_python_ast", version = "0.15.8" }
ruff_text_size = { package = "rustpython-ruff_text_size", version = "0.15.8" }
ruff_source_file = { package = "rustpython-ruff_source_file", version = "0.15.8" }
# To update ruff crates, comment out the above lines and uncomment the following lines to pull directly from the Ruff repository at the specified commit hash.
# Ruff tag 0.15.8 is based on commit c2a8815842f9dc5d24ec19385eae0f1a7188b0d9
# at the time of this capture. We use the commit hash to ensure reproducible builds.
ruff_python_parser = { git = "https://github.com/astral-sh/ruff.git", rev = "e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675" }
ruff_python_ast = { git = "https://github.com/astral-sh/ruff.git", rev = "e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675" }
ruff_text_size = { git = "https://github.com/astral-sh/ruff.git", rev = "e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675" }
ruff_source_file = { git = "https://github.com/astral-sh/ruff.git", rev = "e4c7f357777a2fdd34dbe6a98b1b7d3e7488f675" }
# ruff_python_parser = { git = "https://github.com/astral-sh/ruff.git", rev = "c2a8815842f9dc5d24ec19385eae0f1a7188b0d9" }
# ruff_python_ast = { git = "https://github.com/astral-sh/ruff.git", rev = "c2a8815842f9dc5d24ec19385eae0f1a7188b0d9" }
# ruff_text_size = { git = "https://github.com/astral-sh/ruff.git", rev = "c2a8815842f9dc5d24ec19385eae0f1a7188b0d9" }
# ruff_source_file = { git = "https://github.com/astral-sh/ruff.git", rev = "c2a8815842f9dc5d24ec19385eae0f1a7188b0d9" }
phf = { version = "0.13.1", default-features = false, features = ["macros"]}
ahash = "0.8.12"
@@ -207,7 +214,7 @@ rand_core = { version = "0.9", features = ["os_rng"] }
rustix = { version = "1.1", features = ["event"] }
rustyline = "17.0.1"
serde = { package = "serde_core", version = "1.0.225", default-features = false, features = ["alloc"] }
schannel = "0.1.28"
schannel = "0.1.29"
scoped-tls = "1"
scopeguard = "1"
static_assertions = "1.1"

View File

@@ -99,8 +99,6 @@ class ContextManagerTestCase(unittest.TestCase):
raise ZeroDivisionError()
self.assertEqual(state, [1, 42, 999])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_contextmanager_traceback(self):
@contextmanager
def f():

View File

@@ -252,7 +252,6 @@ class AsyncContextManagerTestCase(unittest.IsolatedAsyncioTestCase):
raise ZeroDivisionError(999)
self.assertEqual(state, [1, 42, 999])
@unittest.expectedFailure # TODO: RUSTPYTHON
async def test_contextmanager_except_stopiter(self):
@asynccontextmanager
async def woohoo():

View File

@@ -2519,7 +2519,6 @@ class SyntaxErrorTests(unittest.TestCase):
self.assertEqual(error, the_exception.text)
self.assertEqual("bad bad", the_exception.msg)
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_incorrect_constructor(self):
args = ("bad.py", 1, 2)
self.assertRaises(TypeError, SyntaxError, "bad bad", args)

View File

@@ -1261,7 +1261,6 @@ class TestLineAndInstructionEvents(CheckEvents):
('instruction', 'func2', 46),
('line', 'get_events', 11)])
@unittest.expectedFailure # TODO: RUSTPYTHON; - instruction offsets differ from CPython
def test_try_except(self):
def func3():

View File

@@ -132,7 +132,6 @@ class TestTranforms(BytecodeTestCase):
self.assertInBytecode(f, 'LOAD_CONST', None)
self.check_lnotab(f)
@unittest.expectedFailure # TODO: RUSTPYTHON; RETURN_VALUE
def test_while_one(self):
# Skip over: LOAD_CONST trueconst POP_JUMP_IF_FALSE xx
def f():
@@ -530,7 +529,6 @@ class TestTranforms(BytecodeTestCase):
self.assertEqual(len(returns), 1)
self.check_lnotab(f)
@unittest.expectedFailure # TODO: RUSTPYTHON; KeyError: 20
def test_elim_jump_to_return(self):
# JUMP_FORWARD to RETURN --> RETURN
def f(cond, true_value, false_value):
@@ -545,7 +543,6 @@ class TestTranforms(BytecodeTestCase):
self.assertEqual(len(returns), 2)
self.check_lnotab(f)
@unittest.expectedFailure # TODO: RUSTPYTHON; absolute jump encoding
def test_elim_jump_to_uncond_jump(self):
# POP_JUMP_IF_FALSE to JUMP_FORWARD --> POP_JUMP_IF_FALSE to non-jump
def f():

View File

@@ -692,7 +692,6 @@ class ScopeTests(unittest.TestCase):
self.assertEqual(c.dec(), 1)
self.assertEqual(c.dec(), 0)
@unittest.expectedFailure # TODO: RUSTPYTHON; figure out how to communicate that `y = 9` should be stored as a global rather than a STORE_NAME, even when the `global y` is in a nested subscope
def testGlobalInParallelNestedFunctions(self):
# A symbol table bug leaked the global statement from one
# function to other nested functions in the same block.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
---
source: crates/codegen/src/compile.rs
assertion_line: 9780
expression: "compile_exec(\"\\\nasync def test():\n for stop_exc in (StopIteration('spam'), StopAsyncIteration('ham')):\n with self.subTest(type=type(stop_exc)):\n try:\n async with egg():\n raise stop_exc\n except Exception as ex:\n self.assertIs(ex, stop_exc)\n else:\n self.fail(f'{stop_exc} was suppressed')\n\")"
---
1 0 RESUME (0)
@@ -24,7 +23,7 @@ expression: "compile_exec(\"\\\nasync def test():\n for stop_exc in (StopIter
16 CACHE
17 CACHE
18 LOAD_CONST ("ham")
>> 19 CALL (1)
19 CALL (1)
20 CACHE
21 CACHE
22 CACHE
@@ -34,12 +33,12 @@ expression: "compile_exec(\"\\\nasync def test():\n for stop_exc in (StopIter
26 CACHE
27 STORE_FAST (0, stop_exc)
3 >> 28 LOAD_GLOBAL (4, self)
3 28 LOAD_GLOBAL (4, self)
29 CACHE
30 CACHE
31 CACHE
32 CACHE
>> 33 LOAD_ATTR (7, subTest, method=true)
>> 32 CACHE
33 LOAD_ATTR (7, subTest, method=true)
34 CACHE
35 CACHE
36 CACHE
@@ -52,9 +51,9 @@ expression: "compile_exec(\"\\\nasync def test():\n for stop_exc in (StopIter
43 LOAD_GLOBAL (9, NULL + type)
44 CACHE
45 CACHE
>> 46 CACHE
46 CACHE
47 CACHE
48 LOAD_FAST (0, stop_exc)
>> 48 LOAD_FAST (0, stop_exc)
49 CALL (1)
50 CACHE
51 CACHE
@@ -139,30 +138,30 @@ expression: "compile_exec(\"\\\nasync def test():\n for stop_exc in (StopIter
125 POP_TOP
126 POP_TOP
127 POP_TOP
128 JUMP_FORWARD (3)
128 JUMP_FORWARD (48)
129 COPY (3)
130 POP_EXCEPT
131 RERAISE (1)
132 JUMP_FORWARD (46)
133 PUSH_EXC_INFO
132 PUSH_EXC_INFO
7 134 LOAD_GLOBAL (12, Exception)
7 133 LOAD_GLOBAL (12, Exception)
134 CACHE
135 CACHE
136 CACHE
137 CACHE
138 CACHE
139 CHECK_EXC_MATCH
140 POP_JUMP_IF_FALSE (33)
141 CACHE
142 NOT_TAKEN
143 STORE_FAST (1, ex)
138 CHECK_EXC_MATCH
139 POP_JUMP_IF_FALSE (32)
140 CACHE
141 NOT_TAKEN
142 STORE_FAST (1, ex)
8 144 LOAD_GLOBAL (4, self)
8 143 LOAD_GLOBAL (4, self)
144 CACHE
145 CACHE
146 CACHE
147 CACHE
148 CACHE
149 LOAD_ATTR (15, assertIs, method=true)
148 LOAD_ATTR (15, assertIs, method=true)
149 CACHE
150 CACHE
151 CACHE
152 CACHE
@@ -171,84 +170,85 @@ expression: "compile_exec(\"\\\nasync def test():\n for stop_exc in (StopIter
155 CACHE
156 CACHE
157 CACHE
158 CACHE
159 LOAD_FAST_LOAD_FAST (ex, stop_exc)
160 CALL (2)
158 LOAD_FAST_LOAD_FAST (ex, stop_exc)
159 CALL (2)
160 CACHE
161 CACHE
162 CACHE
163 CACHE
164 POP_TOP
165 JUMP_FORWARD (4)
166 LOAD_CONST (None)
167 STORE_FAST (1, ex)
168 DELETE_FAST (1, ex)
169 RERAISE (1)
170 POP_EXCEPT
171 LOAD_CONST (None)
172 STORE_FAST (1, ex)
173 DELETE_FAST (1, ex)
174 JUMP_FORWARD (28)
175 RERAISE (0)
176 COPY (3)
177 POP_EXCEPT
178 RERAISE (1)
163 POP_TOP
164 POP_EXCEPT
165 LOAD_CONST (None)
166 STORE_FAST (1, ex)
167 DELETE_FAST (1, ex)
168 JUMP_FORWARD (32)
169 LOAD_CONST (None)
170 STORE_FAST (1, ex)
171 DELETE_FAST (1, ex)
172 RERAISE (1)
173 RERAISE (0)
174 COPY (3)
175 POP_EXCEPT
176 RERAISE (1)
10 179 LOAD_GLOBAL (4, self)
10 177 LOAD_GLOBAL (4, self)
178 CACHE
179 CACHE
180 CACHE
181 CACHE
182 CACHE
182 LOAD_ATTR (17, fail, method=true)
183 CACHE
184 LOAD_ATTR (17, fail, method=true)
184 CACHE
185 CACHE
186 CACHE
187 CACHE
>> 187 CACHE
188 CACHE
189 CACHE
190 CACHE
191 CACHE
192 CACHE
193 CACHE
194 LOAD_FAST_BORROW (0, stop_exc)
195 FORMAT_SIMPLE
196 LOAD_CONST (" was suppressed")
197 BUILD_STRING (2)
198 CALL (1)
192 LOAD_FAST_BORROW (0, stop_exc)
193 FORMAT_SIMPLE
194 LOAD_CONST (" was suppressed")
195 BUILD_STRING (2)
196 CALL (1)
197 CACHE
198 CACHE
199 CACHE
200 CACHE
201 CACHE
202 POP_TOP
203 NOP
200 POP_TOP
201 NOP
3 204 LOAD_CONST (None)
205 LOAD_CONST (None)
206 LOAD_CONST (None)
207 CALL (3)
3 202 LOAD_CONST (None)
203 LOAD_CONST (None)
>> 204 LOAD_CONST (None)
205 CALL (3)
206 CACHE
207 CACHE
208 CACHE
>> 209 CACHE
210 CACHE
211 POP_TOP
212 JUMP_FORWARD (19)
213 PUSH_EXC_INFO
214 WITH_EXCEPT_START
215 TO_BOOL
209 POP_TOP
210 JUMP_BACKWARD (187)
211 CACHE
212 PUSH_EXC_INFO
213 WITH_EXCEPT_START
214 TO_BOOL
215 CACHE
216 CACHE
217 CACHE
218 CACHE
219 POP_JUMP_IF_TRUE (2)
220 CACHE
221 NOT_TAKEN
222 RERAISE (2)
223 POP_TOP
224 POP_EXCEPT
218 POP_JUMP_IF_TRUE (2)
219 CACHE
220 NOT_TAKEN
221 RERAISE (2)
222 POP_TOP
223 POP_EXCEPT
224 POP_TOP
225 POP_TOP
226 POP_TOP
227 POP_TOP
228 JUMP_FORWARD (3)
227 JUMP_BACKWARD (204)
228 CACHE
229 COPY (3)
230 POP_EXCEPT
231 RERAISE (1)
232 JUMP_BACKWARD (209)
233 CACHE
2 232 CALL_INTRINSIC_1 (StopIterationError)
233 RERAISE (1)
2 MAKE_FUNCTION
3 STORE_NAME (0, test)

View File

@@ -2169,17 +2169,15 @@ impl SymbolTableBuilder {
// Generator expressions need the is_generator flag
self.tables.last_mut().unwrap().is_generator = is_generator;
// PEP 709: Mark non-generator comprehensions for inlining,
// but only inside function-like scopes (fastlocals).
// Module/class scope uses STORE_NAME which is incompatible
// with LOAD_FAST_AND_CLEAR / STORE_FAST save/restore.
// Async comprehensions cannot be inlined because they need
// their own coroutine scope.
// Note: tables.last() is the comprehension scope we just pushed,
// so we check the second-to-last for the parent scope.
// PEP 709: Mark non-generator comprehensions for inlining.
// Only in function-like scopes for now. Module/class scope inlining
// needs more work (Cell name resolution, __class__ handling).
// Also excluded: generator expressions, async comprehensions,
// and annotation scopes nested in classes (can_see_class_scope).
let element_has_await = expr_contains_await(elt1) || elt2.is_some_and(expr_contains_await);
if !is_generator && !has_async_gen && !element_has_await {
let parent = self.tables.iter().rev().nth(1);
let parent_can_see_class = parent.is_some_and(|t| t.can_see_class_scope);
let parent_is_func = parent.is_some_and(|t| {
matches!(
t.typ,
@@ -2189,8 +2187,7 @@ impl SymbolTableBuilder {
| CompilerScope::Comprehension
)
});
let parent_can_see_class = parent.is_some_and(|t| t.can_see_class_scope);
if parent_is_func && !parent_can_see_class {
if !parent_can_see_class && parent_is_func {
self.tables.last_mut().unwrap().comp_inlined = true;
}
}

View File

@@ -135,6 +135,72 @@ pub fn decode_exception_table(table: &[u8]) -> Vec<ExceptionTableEntry> {
entries
}
/// Parse linetable to build a boolean mask indicating which code units
/// have NO_LOCATION (line == -1). Returns a Vec<bool> of length `num_units`.
pub fn build_no_location_mask(linetable: &[u8], num_units: usize) -> Vec<bool> {
let mut mask = Vec::new();
mask.resize(num_units, false);
let mut pos = 0;
let mut unit_idx = 0;
while pos < linetable.len() && unit_idx < num_units {
let header = linetable[pos];
pos += 1;
let code = (header >> 3) & 0xf;
let length = ((header & 7) + 1) as usize;
let is_no_location = code == PyCodeLocationInfoKind::None as u8;
// Skip payload bytes based on location kind
match code {
0..=9 => pos += 1, // Short forms: 1 byte payload
10..=12 => pos += 2, // OneLine forms: 2 bytes payload
13 => {
// NoColumns: signed varint (line delta)
while pos < linetable.len() {
let b = linetable[pos];
pos += 1;
if b & 0x40 == 0 {
break;
}
}
}
14 => {
// Long form: signed varint (line delta) + 3 unsigned varints
// line_delta
while pos < linetable.len() {
let b = linetable[pos];
pos += 1;
if b & 0x40 == 0 {
break;
}
}
// end_line_delta, col+1, end_col+1
for _ in 0..3 {
while pos < linetable.len() {
let b = linetable[pos];
pos += 1;
if b & 0x40 == 0 {
break;
}
}
}
}
15 => {} // None: no payload
_ => {}
}
for _ in 0..length {
if unit_idx < num_units {
mask[unit_idx] = is_no_location;
unit_idx += 1;
}
}
}
mask
}
/// CPython 3.11+ linetable location info codes
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u8)]
@@ -226,6 +292,8 @@ impl Constant for ConstantData {
Self::Bytes { value } => Bytes { value },
Self::Code { code } => Code { code },
Self::Tuple { elements } => Tuple { elements },
Self::Slice { elements } => Slice { elements },
Self::Frozenset { elements } => Frozenset { elements },
Self::None => None,
Self::Ellipsis => Ellipsis,
}
@@ -783,14 +851,37 @@ impl CodeUnits {
/// ```
#[derive(Debug, Clone)]
pub enum ConstantData {
Tuple { elements: Vec<ConstantData> },
Integer { value: BigInt },
Float { value: f64 },
Complex { value: Complex64 },
Boolean { value: bool },
Str { value: Wtf8Buf },
Bytes { value: Vec<u8> },
Code { code: Box<CodeObject> },
Tuple {
elements: Vec<ConstantData>,
},
Integer {
value: BigInt,
},
Float {
value: f64,
},
Complex {
value: Complex64,
},
Boolean {
value: bool,
},
Str {
value: Wtf8Buf,
},
Bytes {
value: Vec<u8>,
},
Code {
code: Box<CodeObject>,
},
/// Constant slice(start, stop, step)
Slice {
elements: Box<[ConstantData; 3]>,
},
Frozenset {
elements: Vec<ConstantData>,
},
None,
Ellipsis,
}
@@ -812,6 +903,8 @@ impl PartialEq for ConstantData {
(Bytes { value: a }, Bytes { value: b }) => a == b,
(Code { code: a }, Code { code: b }) => core::ptr::eq(a.as_ref(), b.as_ref()),
(Tuple { elements: a }, Tuple { elements: b }) => a == b,
(Slice { elements: a }, Slice { elements: b }) => a == b,
(Frozenset { elements: a }, Frozenset { elements: b }) => a == b,
(None, None) => true,
(Ellipsis, Ellipsis) => true,
_ => false,
@@ -838,6 +931,8 @@ impl hash::Hash for ConstantData {
Bytes { value } => value.hash(state),
Code { code } => core::ptr::hash(code.as_ref(), state),
Tuple { elements } => elements.hash(state),
Slice { elements } => elements.hash(state),
Frozenset { elements } => elements.hash(state),
None => {}
Ellipsis => {}
}
@@ -854,6 +949,8 @@ pub enum BorrowedConstant<'a, C: Constant> {
Bytes { value: &'a [u8] },
Code { code: &'a CodeObject<C> },
Tuple { elements: &'a [C] },
Slice { elements: &'a [C; 3] },
Frozenset { elements: &'a [C] },
None,
Ellipsis,
}
@@ -891,6 +988,28 @@ impl<C: Constant> BorrowedConstant<'_, C> {
}
write!(f, ")")
}
BorrowedConstant::Slice { elements } => {
write!(f, "slice(")?;
elements[0].borrow_constant().fmt_display(f)?;
write!(f, ", ")?;
elements[1].borrow_constant().fmt_display(f)?;
write!(f, ", ")?;
elements[2].borrow_constant().fmt_display(f)?;
write!(f, ")")
}
BorrowedConstant::Frozenset { elements } => {
write!(f, "frozenset({{")?;
let mut first = true;
for c in *elements {
if first {
first = false
} else {
write!(f, ", ")?;
}
c.borrow_constant().fmt_display(f)?;
}
write!(f, "}})")
}
BorrowedConstant::None => write!(f, "None"),
BorrowedConstant::Ellipsis => write!(f, "..."),
}
@@ -921,6 +1040,15 @@ impl<C: Constant> BorrowedConstant<'_, C> {
.map(|c| c.borrow_constant().to_owned())
.collect(),
},
BorrowedConstant::Slice { elements } => Slice {
elements: Box::new(elements.each_ref().map(|c| c.borrow_constant().to_owned())),
},
BorrowedConstant::Frozenset { elements } => Frozenset {
elements: elements
.iter()
.map(|c| c.borrow_constant().to_owned())
.collect(),
},
BorrowedConstant::None => None,
BorrowedConstant::Ellipsis => Ellipsis,
}

View File

@@ -645,6 +645,10 @@ oparg_enum!(
BuiltinAll = 3,
/// Built-in `any` function
BuiltinAny = 4,
/// Built-in `list` type
BuiltinList = 5,
/// Built-in `set` type
BuiltinSet = 6,
}
);
@@ -656,6 +660,8 @@ impl fmt::Display for CommonConstant {
Self::BuiltinTuple => "tuple",
Self::BuiltinAll => "all",
Self::BuiltinAny => "any",
Self::BuiltinList => "list",
Self::BuiltinSet => "set",
};
write!(f, "{name}")
}
@@ -918,8 +924,8 @@ impl VarNums {
impl LoadAttr {
#[must_use]
pub fn builder() -> LoadAttrBuilder {
LoadAttrBuilder::default()
pub const fn new(name_idx: u32, is_method: bool) -> Self {
Self::from_u32((name_idx << 1) | (is_method as u32))
}
#[must_use]
@@ -933,36 +939,10 @@ impl LoadAttr {
}
}
#[derive(Clone, Copy, Default)]
pub struct LoadAttrBuilder {
name_idx: u32,
is_method: bool,
}
impl LoadAttrBuilder {
#[must_use]
pub const fn build(self) -> LoadAttr {
let value = (self.name_idx << 1) | (self.is_method as u32);
LoadAttr::from_u32(value)
}
#[must_use]
pub const fn name_idx(mut self, value: u32) -> Self {
self.name_idx = value;
self
}
#[must_use]
pub const fn is_method(mut self, value: bool) -> Self {
self.is_method = value;
self
}
}
impl LoadSuperAttr {
#[must_use]
pub fn builder() -> LoadSuperAttrBuilder {
LoadSuperAttrBuilder::default()
pub const fn new(name_idx: u32, is_load_method: bool, has_class: bool) -> Self {
Self::from_u32((name_idx << 2) | (is_load_method as u32) | ((has_class as u32) << 1))
}
#[must_use]
@@ -980,43 +960,3 @@ impl LoadSuperAttr {
(self.0 & 2) == 2
}
}
#[derive(Clone, Copy, Default)]
pub struct LoadSuperAttrBuilder {
name_idx: u32,
is_load_method: bool,
has_class: bool,
}
impl LoadSuperAttrBuilder {
#[must_use]
pub const fn build(self) -> LoadSuperAttr {
let value =
(self.name_idx << 2) | ((self.has_class as u32) << 1) | (self.is_load_method as u32);
LoadSuperAttr::from_u32(value)
}
#[must_use]
pub const fn name_idx(mut self, value: u32) -> Self {
self.name_idx = value;
self
}
#[must_use]
pub const fn is_load_method(mut self, value: bool) -> Self {
self.is_load_method = value;
self
}
#[must_use]
pub const fn has_class(mut self, value: bool) -> Self {
self.has_class = value;
self
}
}
impl From<LoadSuperAttrBuilder> for LoadSuperAttr {
fn from(builder: LoadSuperAttrBuilder) -> Self {
builder.build()
}
}

View File

@@ -435,6 +435,20 @@ impl<Bag: ConstantBag> MarshalBag for Bag {
self.make_tuple(elements)
}
fn make_slice(
&self,
start: Self::Value,
stop: Self::Value,
step: Self::Value,
) -> Result<Self::Value> {
let elements = [start, stop, step];
Ok(
self.make_constant::<Bag::Constant>(BorrowedConstant::Slice {
elements: &elements,
}),
)
}
fn make_code(
&self,
code: CodeObject<<Self::ConstantBag as ConstantBag>::Constant>,
@@ -454,8 +468,13 @@ impl<Bag: ConstantBag> MarshalBag for Bag {
Err(MarshalError::BadType)
}
fn make_frozenset(&self, _: impl Iterator<Item = Self::Value>) -> Result<Self::Value> {
Err(MarshalError::BadType)
fn make_frozenset(&self, it: impl Iterator<Item = Self::Value>) -> Result<Self::Value> {
let elements: Vec<Self::Value> = it.collect();
Ok(
self.make_constant::<Bag::Constant>(BorrowedConstant::Frozenset {
elements: &elements,
}),
)
}
fn make_dict(
@@ -697,6 +716,10 @@ impl<'a, C: Constant> From<BorrowedConstant<'a, C>> for DumpableValue<'a, C> {
BorrowedConstant::Bytes { value } => Self::Bytes(value),
BorrowedConstant::Code { code } => Self::Code(code),
BorrowedConstant::Tuple { elements } => Self::Tuple(elements),
BorrowedConstant::Slice { elements } => {
Self::Slice(&elements[0], &elements[1], &elements[2])
}
BorrowedConstant::Frozenset { elements } => Self::Frozenset(elements),
BorrowedConstant::None => Self::None,
BorrowedConstant::Ellipsis => Self::Ellipsis,
}

View File

@@ -1,7 +1,7 @@
[package]
name = "rustpython-compiler-source"
description = "(DEPRECATED) RustPython Source and Index"
version = "0.5.0+deprecated"
version = "0.4.1+deprecated"
authors.workspace = true
edition.workspace = true
rust-version.workspace = true

View File

@@ -1,5 +1,6 @@
[package]
name = "rustpython-doc"
description = "Python __doc__ database for RustPython"
version.workspace = true
authors.workspace = true
edition.workspace = true

View File

@@ -736,6 +736,20 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
self.store_variable(var_num.get(arg), val)
}
Instruction::StoreFastLoadFast { var_nums } => {
let oparg = var_nums.get(arg);
let (store_idx, load_idx) = oparg.indexes();
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
self.store_variable(store_idx, val)?;
let local = self.variables[load_idx]
.as_ref()
.ok_or(JitCompileError::BadBytecode)?;
self.stack.push(JitValue::from_type_and_value(
local.ty.clone(),
self.builder.use_var(local.var),
));
Ok(())
}
Instruction::StoreFastStoreFast { var_nums } => {
let oparg = var_nums.get(arg);
let (idx1, idx2) = oparg.indexes();

View File

@@ -42,6 +42,7 @@ impl Function {
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
enum StackValue {
String(String),
@@ -49,6 +50,8 @@ enum StackValue {
Map(HashMap<Wtf8Buf, StackValue>),
Code(Box<CodeObject>),
Function(Function),
Slice(Box<[StackValue; 3]>),
Frozenset(Vec<StackValue>),
}
impl From<ConstantData> for StackValue {
@@ -59,6 +62,13 @@ impl From<ConstantData> for StackValue {
}
ConstantData::None => StackValue::None,
ConstantData::Code { code } => StackValue::Code(code),
ConstantData::Slice { elements } => {
let [start, stop, step] = *elements;
StackValue::Slice(Box::new([start.into(), stop.into(), step.into()]))
}
ConstantData::Frozenset { elements } => {
StackValue::Frozenset(elements.into_iter().map(Into::into).collect())
}
c => unimplemented!("constant {:?} isn't yet supported in py_function!", c),
}
}

View File

@@ -2,7 +2,7 @@
name = "rustpython-pylib"
description = "A subset of the Python standard library for use with RustPython"
license-file = "Lib/PSF-LICENSE"
include = ["Cargo.toml", "src/**/*.rs", "Lib/", "!Lib/**/test/", "!Lib/**/*.pyc"]
include = ["Cargo.toml", "build.rs", "src/**/*.rs", "Lib/", "!Lib/**/test/", "!Lib/**/*.pyc"]
authors = ["CPython Developers"]
version.workspace = true
edition.workspace = true

View File

@@ -94,8 +94,8 @@ libz-sys = { package = "libz-rs-sys", version = "0.5" }
bzip2 = "0.6"
# tkinter
tk-sys = { git = "https://github.com/arihant2math/tkinter.git", tag = "v0.2.0", optional = true }
tcl-sys = { git = "https://github.com/arihant2math/tkinter.git", tag = "v0.2.0", optional = true }
tk-sys = { version = "0.2.0", optional = true }
tcl-sys = { version = "0.2.0", optional = true }
widestring = { workspace = true, optional = true }
chrono.workspace = true

View File

@@ -232,6 +232,23 @@ fn borrow_obj_constant(obj: &PyObject) -> BorrowedConstant<'_, Literal> {
}
super::singletons::PyNone => BorrowedConstant::None,
super::slice::PyEllipsis => BorrowedConstant::Ellipsis,
ref s @ super::slice::PySlice => {
// Constant pool slices always store Some() for start/step (even for None).
// Box::leak the array so it outlives the borrow. Leak is acceptable since
// constant pool objects live for the program's lifetime.
let start = s.start.clone().unwrap();
let stop = s.stop.clone();
let step = s.step.clone().unwrap();
let arr = Box::leak(Box::new([Literal(start), Literal(stop), Literal(step)]));
BorrowedConstant::Slice { elements: arr }
}
ref fs @ super::set::PyFrozenSet => {
// Box::leak the elements so they outlive the borrow. Leak is acceptable since
// constant pool objects live for the program's lifetime.
let elems: Vec<Literal> = fs.elements().into_iter().map(Literal).collect();
let elements = Box::leak(elems.into_boxed_slice());
BorrowedConstant::Frozenset { elements }
}
_ => panic!("unexpected payload for constant python value"),
})
}
@@ -283,6 +300,30 @@ impl ConstantBag for PyObjBag<'_> {
.collect();
ctx.new_tuple(elements).into()
}
BorrowedConstant::Slice { elements } => {
let [start, stop, step] = elements;
let start_obj = self.make_constant(start.borrow_constant()).0;
let stop_obj = self.make_constant(stop.borrow_constant()).0;
let step_obj = self.make_constant(step.borrow_constant()).0;
// Store as PySlice with Some() for all fields (even None values)
// so borrow_obj_constant can reference them.
use crate::builtins::PySlice;
PySlice {
start: Some(start_obj),
stop: stop_obj,
step: Some(step_obj),
}
.into_ref(ctx)
.into()
}
BorrowedConstant::Frozenset { elements: _ } => {
// Creating a frozenset requires VirtualMachine for element hashing.
// PyObjBag only has Context, so we cannot construct PyFrozenSet here.
// Frozenset constants from .pyc are handled by PyMarshalBag which has VM access.
unimplemented!(
"frozenset constant in PyObjBag::make_constant requires VirtualMachine"
)
}
BorrowedConstant::None => ctx.none(),
BorrowedConstant::Ellipsis => ctx.ellipsis.clone().into(),
};

View File

@@ -2397,6 +2397,22 @@ pub(super) mod types {
.downcast::<crate::builtins::PyTuple>()
{
let location_tup_len = location_tuple.len();
match location_tup_len {
4 | 6 => {}
5 => {
return Err(vm.new_type_error(
"end_offset must be provided when end_lineno is provided".to_owned(),
));
}
_ => {
return Err(vm.new_type_error(format!(
"function takes exactly 4 or 6 arguments ({} given)",
location_tup_len
)));
}
}
for (i, &attr) in [
"filename",
"lineno",

View File

@@ -1755,12 +1755,6 @@ impl ExecutingFrame<'_> {
exc_tb: PyObjectRef,
) -> PyResult<ExecutionResult> {
self.monitoring_mask = vm.state.monitoring_events.load();
// Reset prev_line so that LINE monitoring events fire even if
// the exception handler is on the same line as the yield point.
// In CPython, _Py_call_instrumentation_line has a special case
// for RESUME: it fires LINE even when prev_line == current_line.
// Since gen_throw bypasses RESUME, we reset prev_line instead.
*self.prev_line = 0;
if let Some(jen) = self.yield_from_target() {
// Check if the exception is GeneratorExit (type or instance).
// For GeneratorExit, close the sub-iterator instead of throwing.
@@ -1796,7 +1790,10 @@ impl ExecutingFrame<'_> {
self.push_value(vm.ctx.none());
vm.contextualize_exception(&err);
return match self.unwind_blocks(vm, UnwindReason::Raising { exception: err }) {
Ok(None) => self.run(vm),
Ok(None) => {
*self.prev_line = 0;
self.run(vm)
}
Ok(Some(result)) => Ok(result),
Err(exception) => Err(exception),
};
@@ -1838,7 +1835,10 @@ impl ExecutingFrame<'_> {
self.push_value(vm.ctx.none());
vm.contextualize_exception(&err);
match self.unwind_blocks(vm, UnwindReason::Raising { exception: err }) {
Ok(None) => self.run(vm),
Ok(None) => {
*self.prev_line = 0;
self.run(vm)
}
Ok(Some(result)) => Ok(result),
Err(exception) => Err(exception),
}
@@ -1906,7 +1906,13 @@ impl ExecutingFrame<'_> {
self.push_value(vm.ctx.none());
match self.unwind_blocks(vm, UnwindReason::Raising { exception }) {
Ok(None) => self.run(vm),
Ok(None) => {
// Reset prev_line so that the first instruction in the handler
// fires a LINE event. In CPython, gen_send_ex re-enters the
// eval loop which reinitializes its local prev_instr tracker.
*self.prev_line = 0;
self.run(vm)
}
Ok(Some(result)) => Ok(result),
Err(exception) => {
// Fire PY_UNWIND: exception escapes the generator frame.
@@ -2780,8 +2786,18 @@ impl ExecutingFrame<'_> {
vm.ctx.exceptions.not_implemented_error.to_owned().into()
}
CommonConstant::BuiltinTuple => vm.ctx.types.tuple_type.to_owned().into(),
CommonConstant::BuiltinAll => vm.builtins.get_attr("all", vm)?,
CommonConstant::BuiltinAny => vm.builtins.get_attr("any", vm)?,
CommonConstant::BuiltinAll => vm
.callable_cache
.builtin_all
.clone()
.expect("builtin_all not initialized"),
CommonConstant::BuiltinAny => vm
.callable_cache
.builtin_any
.clone()
.expect("builtin_any not initialized"),
CommonConstant::BuiltinList => vm.ctx.types.list_type.to_owned().into(),
CommonConstant::BuiltinSet => vm.ctx.types.set_type.to_owned().into(),
};
self.push_value(value);
Ok(None)
@@ -9440,20 +9456,25 @@ impl ExecutingFrame<'_> {
Ok(vm.ctx.new_tuple(list.borrow_vec().to_vec()).into())
}
bytecode::IntrinsicFunction1::StopIterationError => {
// Convert StopIteration to RuntimeError
// Used to ensure async generators don't raise StopIteration directly
// _PyGen_FetchStopIterationValue
// Use fast_isinstance to handle subclasses of StopIteration
// Convert StopIteration to RuntimeError (PEP 479)
// Returns the exception object; RERAISE will re-raise it
if arg.fast_isinstance(vm.ctx.exceptions.stop_iteration) {
Err(vm.new_runtime_error("coroutine raised StopIteration"))
let flags = &self.code.flags;
let msg = if flags
.contains(bytecode::CodeFlags::COROUTINE | bytecode::CodeFlags::GENERATOR)
{
"async generator raised StopIteration"
} else if flags.contains(bytecode::CodeFlags::COROUTINE) {
"coroutine raised StopIteration"
} else {
"generator raised StopIteration"
};
let err = vm.new_runtime_error(msg);
err.set___cause__(arg.downcast().ok());
Ok(err.into())
} else {
// If not StopIteration, just re-raise the original exception
Err(arg.downcast().unwrap_or_else(|obj| {
vm.new_runtime_error(format!(
"unexpected exception type: {:?}",
obj.class()
))
}))
// Not StopIteration, pass through for RERAISE
Ok(arg)
}
}
bytecode::IntrinsicFunction1::AsyncGenWrap => {

View File

@@ -174,6 +174,14 @@ mod _symtable {
.symtable
.sub_tables
.iter()
.flat_map(|t| {
if t.comp_inlined {
// Flatten: replace inlined comprehension tables with their children
t.sub_tables.iter().collect::<Vec<_>>()
} else {
vec![t]
}
})
.map(|t| to_py_symbol_table(t.clone()).into_pyobject(vm))
.collect();
Ok(children)

View File

@@ -368,6 +368,9 @@ pub fn instrument_code(code: &PyCode, events: u32) {
// is_line_start[i] = true if position i should have INSTRUMENTED_LINE
let mut is_line_start = vec![false; len];
// Build NO_LOCATION mask from linetable
let no_loc_mask = bytecode::build_no_location_mask(&code.code.linetable, len);
// First pass: mark positions where the source line changes
let mut prev_line: Option<u32> = None;
for (i, unit) in code
@@ -395,6 +398,10 @@ pub fn instrument_code(code: &PyCode, events: u32) {
) {
continue;
}
// Skip NO_LOCATION instructions
if no_loc_mask.get(i).copied().unwrap_or(false) {
continue;
}
if let Some((loc, _)) = code.code.locations.get(i) {
let line = loc.line.get() as u32;
let is_new = prev_line != Some(line);
@@ -445,6 +452,7 @@ pub fn instrument_code(code: &PyCode, events: u32) {
if let Some(target_idx) = target
&& target_idx < len
&& !is_line_start[target_idx]
&& !no_loc_mask.get(target_idx).copied().unwrap_or(false)
{
let target_op = code.code.instructions[target_idx].op;
let target_base = target_op.to_base().map_or(target_op, |b| b);
@@ -465,7 +473,10 @@ pub fn instrument_code(code: &PyCode, events: u32) {
// Third pass: mark exception handler targets as line starts.
for entry in bytecode::decode_exception_table(&code.code.exceptiontable) {
let target_idx = entry.target as usize;
if target_idx < len && !is_line_start[target_idx] {
if target_idx < len
&& !is_line_start[target_idx]
&& !no_loc_mask.get(target_idx).copied().unwrap_or(false)
{
let target_op = code.code.instructions[target_idx].op;
let target_base = target_op.to_base().map_or(target_op, |b| b);
if !matches!(target_base, Instruction::PopIter)

View File

@@ -129,8 +129,8 @@ pub fn get_git_datetime() -> String {
}
// Must be aligned to Lib/importlib/_bootstrap_external.py
// Bumped to 2997 for MAKE_CELL/COPY_FREE_VARS prolog and cell-local merging
pub const PYC_MAGIC_NUMBER: u16 = 2997;
// Bumped to 2994 for new CommonConstant discriminants (BuiltinList, BuiltinSet)
pub const PYC_MAGIC_NUMBER: u16 = 2994;
// CPython format: magic_number | ('\r' << 16) | ('\n' << 24)
// This protects against text-mode file reads

View File

@@ -576,6 +576,8 @@ pub(crate) struct CallableCache {
pub len: Option<PyObjectRef>,
pub isinstance: Option<PyObjectRef>,
pub list_append: Option<PyObjectRef>,
pub builtin_all: Option<PyObjectRef>,
pub builtin_any: Option<PyObjectRef>,
}
pub struct PyGlobalState {
@@ -641,6 +643,8 @@ impl VirtualMachine {
.get_attr(self.ctx.intern_str("append"))
.ok_or_else(|| self.new_runtime_error("failed to cache list.append".to_owned()))?;
self.callable_cache.list_append = Some(list_append);
self.callable_cache.builtin_all = Some(self.builtins.get_attr("all", self)?);
self.callable_cache.builtin_any = Some(self.builtins.get_attr("any", self)?);
Ok(())
}

View File

@@ -21,7 +21,7 @@
"css-loader": "^7.1.2",
"html-webpack-plugin": "^5.6.3",
"mini-css-extract-plugin": "^2.9.2",
"serve": "^14.2.5",
"serve": "^14.2.6",
"webpack": "^5.105.0",
"webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.1"
@@ -839,9 +839,9 @@
}
},
"node_modules/ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1129,9 +1129,9 @@
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
"integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3448,9 +3448,9 @@
"license": "ISC"
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -4003,16 +4003,6 @@
"node": ">= 0.10"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
@@ -4375,14 +4365,14 @@
}
},
"node_modules/serve": {
"version": "14.2.5",
"resolved": "https://registry.npmjs.org/serve/-/serve-14.2.5.tgz",
"integrity": "sha512-Qn/qMkzCcMFVPb60E/hQy+iRLpiU8PamOfOSYoAHmmF+fFFmpPpqa6Oci2iWYpTdOUM3VF+TINud7CfbQnsZbA==",
"version": "14.2.6",
"resolved": "https://registry.npmjs.org/serve/-/serve-14.2.6.tgz",
"integrity": "sha512-QEjUSA+sD4Rotm1znR8s50YqA3kYpRGPmtd5GlFxbaL9n/FdUNbqMhxClqdditSk0LlZyA/dhud6XNRTOC9x2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@zeit/schemas": "2.36.0",
"ajv": "8.12.0",
"ajv": "8.18.0",
"arg": "5.0.2",
"boxen": "7.0.0",
"chalk": "5.0.1",
@@ -4390,7 +4380,7 @@
"clipboardy": "3.0.0",
"compression": "1.8.1",
"is-port-reachable": "4.0.0",
"serve-handler": "6.1.6",
"serve-handler": "6.1.7",
"update-check": "1.5.4"
},
"bin": {
@@ -4401,16 +4391,16 @@
}
},
"node_modules/serve-handler": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz",
"integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==",
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.7.tgz",
"integrity": "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==",
"dev": true,
"license": "MIT",
"dependencies": {
"bytes": "3.0.0",
"content-disposition": "0.5.2",
"mime-types": "2.1.18",
"minimatch": "3.1.2",
"minimatch": "3.1.5",
"path-is-inside": "1.0.2",
"path-to-regexp": "3.3.0",
"range-parser": "1.2.0"
@@ -4524,23 +4514,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/serve/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/serve/node_modules/chalk": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
@@ -5203,16 +5176,6 @@
"integrity": "sha512-NtkVvqVCqsJo5U3mYRum2Tw6uCltOxfIJ/AfTZeTmw6U39IB5X23xF+kRZ9aiPaORqeiQQ7Q209/ibhOvxzwHA==",
"license": "MIT"
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View File

@@ -16,7 +16,7 @@
"css-loader": "^7.1.2",
"html-webpack-plugin": "^5.6.3",
"mini-css-extract-plugin": "^2.9.2",
"serve": "^14.2.5",
"serve": "^14.2.6",
"webpack": "^5.105.0",
"webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.1"