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
36 changed files with 3419 additions and 818 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.

View File

@@ -2414,6 +2414,7 @@ class StrTest(string_tests.StringLikeTest,
else:
self.fail("Should have raised UnicodeDecodeError")
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: <class 'str'> is not <class 'test.test_str.StrSubclass'>
def test_conversion(self):
# Make sure __str__() works properly
class StrWithStr(str):

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

@@ -394,10 +394,13 @@ impl Constructor for PyStr {
type Args = StrArgs;
fn slot_new(cls: PyTypeRef, func_args: FuncArgs, vm: &VirtualMachine) -> PyResult {
// Optimization: for exact str, return PyObject_Str result as-is
if cls.is(vm.ctx.types.str_type) && func_args.args.len() == 1 && func_args.kwargs.is_empty()
// Optimization: return exact str as-is (only when no encoding/errors provided)
if cls.is(vm.ctx.types.str_type)
&& func_args.args.len() == 1
&& func_args.kwargs.is_empty()
&& func_args.args[0].class().is(vm.ctx.types.str_type)
{
return func_args.args[0].str(vm).map(Into::into);
return Ok(func_args.args[0].clone());
}
let args: Self::Args = func_args.bind(vm)?;

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

@@ -19,33 +19,6 @@ assert type(str(y)) is str, "Str of a str-subtype should be a str."
assert y + " other" == "1 other"
assert y.x == "substr"
class ReprStrSubclass(str):
pass
class WithStr:
def __init__(self, value):
self.value = value
def __str__(self):
return self.value
class WithRepr:
def __init__(self, value):
self.value = value
def __repr__(self):
return self.value
str_value = ReprStrSubclass("abc")
assert str(WithStr(str_value)) is str_value
repr_value = ReprStrSubclass("<abc>")
assert str(WithRepr(repr_value)) is repr_value
## Base strings currently get an attribute dict, but shouldn't.
# with assert_raises(AttributeError):
# "hello".x = 5

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"