mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Compare commits
19 Commits
2025-05-12
...
2025-06-16
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c968fe0fd9 | ||
|
|
125f14190a | ||
|
|
a6dd2d805b | ||
|
|
6723bf30a7 | ||
|
|
2c61a12bed | ||
|
|
f560b4cbfb | ||
|
|
4e094eaa55 | ||
|
|
2e368baf2a | ||
|
|
323ea3b96b | ||
|
|
e27d03179f | ||
|
|
81a9002ef2 | ||
|
|
18521290bf | ||
|
|
5e682e3f17 | ||
|
|
163296d306 | ||
|
|
1ae98ee177 | ||
|
|
2c02e2776b | ||
|
|
72dc4954ad | ||
|
|
b696e56c5f | ||
|
|
d11d5c65e6 |
6
.devcontainer/Dockerfile
Normal file
6
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/rust:1-bullseye
|
||||
|
||||
# Install clang
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y clang \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -1,4 +1,25 @@
|
||||
{
|
||||
"image": "mcr.microsoft.com/devcontainers/base:jammy",
|
||||
"onCreateCommand": "curl https://sh.rustup.rs -sSf | sh -s -- -y"
|
||||
}
|
||||
"name": "Rust",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
"lldb.executable": "/usr/bin/lldb",
|
||||
// VS Code don't watch files under ./target
|
||||
"files.watcherExclude": {
|
||||
"**/target/**": true
|
||||
},
|
||||
"extensions": [
|
||||
"rust-lang.rust-analyzer",
|
||||
"tamasfe.even-better-toml",
|
||||
"vadimcn.vscode-lldb",
|
||||
"mutantdino.resourcemonitor"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"remoteUser": "vscode"
|
||||
}
|
||||
|
||||
9
.github/workflows/ci.yaml
vendored
9
.github/workflows/ci.yaml
vendored
@@ -32,11 +32,6 @@ env:
|
||||
test_pathlib
|
||||
test_posixpath
|
||||
test_venv
|
||||
# configparser: https://github.com/RustPython/RustPython/issues/4995#issuecomment-1582397417
|
||||
# socketserver: seems related to configparser crash.
|
||||
MACOS_SKIPS: >-
|
||||
test_configparser
|
||||
test_socketserver
|
||||
# PLATFORM_INDEPENDENT_TESTS are tests that do not depend on the underlying OS. They are currently
|
||||
# only run on Linux to speed up the CI.
|
||||
PLATFORM_INDEPENDENT_TESTS: >-
|
||||
@@ -284,7 +279,7 @@ jobs:
|
||||
run: target/release/rustpython -m test -j 1 -u all --slowest --fail-env-changed -v -x ${{ env.PLATFORM_INDEPENDENT_TESTS }}
|
||||
- if: runner.os == 'macOS'
|
||||
name: run cpython platform-dependent tests (MacOS)
|
||||
run: target/release/rustpython -m test -j 1 --slowest --fail-env-changed -v -x ${{ env.PLATFORM_INDEPENDENT_TESTS }} ${{ env.MACOS_SKIPS }}
|
||||
run: target/release/rustpython -m test -j 1 --slowest --fail-env-changed -v -x ${{ env.PLATFORM_INDEPENDENT_TESTS }}
|
||||
- if: runner.os == 'Windows'
|
||||
name: run cpython platform-dependent tests (windows partial - fixme)
|
||||
run:
|
||||
@@ -340,7 +335,7 @@ jobs:
|
||||
- name: install extra dictionaries
|
||||
run: npm install @cspell/dict-en_us @cspell/dict-cpp @cspell/dict-python @cspell/dict-rust @cspell/dict-win32 @cspell/dict-shell
|
||||
- name: spell checker
|
||||
uses: streetsidesoftware/cspell-action@v6
|
||||
uses: streetsidesoftware/cspell-action@v7
|
||||
with:
|
||||
files: '**/*.rs'
|
||||
incremental_files_only: true
|
||||
|
||||
272
Cargo.lock
generated
272
Cargo.lock
generated
@@ -16,15 +16,15 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
version = "0.8.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom 0.2.15",
|
||||
"getrandom 0.3.2",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy 0.7.35",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -115,9 +115,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.97"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
@@ -178,7 +178,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -213,9 +213,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.11.3"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0"
|
||||
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
@@ -233,9 +233,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.22.0"
|
||||
version = "1.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
|
||||
checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
@@ -283,9 +283,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.18"
|
||||
version = "1.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c"
|
||||
checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
@@ -313,9 +313,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.40"
|
||||
version = "0.4.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
|
||||
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
@@ -365,18 +365,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.36"
|
||||
version = "4.5.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04"
|
||||
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.36"
|
||||
version = "4.5.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5"
|
||||
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
@@ -850,9 +850,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "error-code"
|
||||
version = "3.3.1"
|
||||
version = "3.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
|
||||
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
|
||||
|
||||
[[package]]
|
||||
name = "exitcode"
|
||||
@@ -963,9 +963,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed7131e57abbde63513e0e6636f76668a1ca9798dcae2df4e283cae9ee83859e"
|
||||
checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"windows-targets 0.52.6",
|
||||
@@ -982,15 +982,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1026,9 +1024,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1"
|
||||
checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crunchy",
|
||||
@@ -1036,9 +1034,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
|
||||
dependencies = [
|
||||
"foldhash",
|
||||
]
|
||||
@@ -1057,9 +1055,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
|
||||
checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
@@ -1124,14 +1122,12 @@ checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.42.2"
|
||||
version = "1.43.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50259abbaa67d11d2bcafc7ba1d094ed7a0c70e3ce893f0d0997f73558cb3084"
|
||||
checksum = "154934ea70c58054b556dd430b99a98c2a7ff5309ac9891597e339b5c28f4371"
|
||||
dependencies = [
|
||||
"console",
|
||||
"linked-hash-map",
|
||||
"once_cell",
|
||||
"pin-project",
|
||||
"similar",
|
||||
]
|
||||
|
||||
@@ -1144,7 +1140,7 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1153,7 +1149,7 @@ version = "0.4.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
||||
dependencies = [
|
||||
"hermit-abi 0.5.0",
|
||||
"hermit-abi 0.5.1",
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
@@ -1199,9 +1195,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "jiff"
|
||||
version = "0.2.5"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260"
|
||||
checksum = "f02000660d30638906021176af16b17498bd0d12813dbfe7b276d8bc7f3c0806"
|
||||
dependencies = [
|
||||
"jiff-static",
|
||||
"log",
|
||||
@@ -1212,13 +1208,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "jiff-static"
|
||||
version = "0.2.5"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c"
|
||||
checksum = "f3c30758ddd7188629c6713fc45d1188af4f44c90582311d0c8d8c9907f60c48"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1300,15 +1296,15 @@ checksum = "0864a00c8d019e36216b69c2c4ce50b83b7bd966add3cf5ba554ec44f8bebcf5"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.171"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "libffi"
|
||||
version = "4.0.0"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a9434b6fc77375fb624698d5f8c49d7e80b10d59eb1219afda27d1f824d4074"
|
||||
checksum = "ebfd30a67b482a08116e753d0656cb626548cf4242543e5cc005be7639d99838"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libffi-sys",
|
||||
@@ -1316,9 +1312,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libffi-sys"
|
||||
version = "3.2.0"
|
||||
version = "3.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ead36a2496acfc8edd6cc32352110e9478ac5b9b5f5b9856ebd3d28019addb84"
|
||||
checksum = "f003aa318c9f0ee69eb0ada7c78f5c9d2fedd2ceb274173b5c7ff475eee584a3"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
@@ -1335,9 +1331,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.11"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
|
||||
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
@@ -1369,17 +1365,11 @@ dependencies = [
|
||||
"zlib-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
@@ -1537,9 +1527,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.7"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430"
|
||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
@@ -1639,7 +1629,7 @@ checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1677,7 +1667,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1688,18 +1678,18 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "300.4.2+3.4.1"
|
||||
version = "300.5.0+3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2"
|
||||
checksum = "e8ce546f549326b0e6052b649198487d91320875da901e7bd11a06d1ee3f9c2f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.107"
|
||||
version = "0.9.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
|
||||
checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -1742,7 +1732,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall 0.5.11",
|
||||
"redox_syscall 0.5.12",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
@@ -1791,26 +1781,6 @@ dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
@@ -1853,7 +1823,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1877,7 +1847,7 @@ version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy 0.8.24",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1887,14 +1857,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.94"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -1910,9 +1880,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17da310086b068fbdcefbba30aeb3721d5bb9af8db4987d6735b2183ca567229"
|
||||
checksum = "e5203598f366b11a02b13aa20cab591229ff0a89fd121a308a5df751d5fc9219"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"indoc",
|
||||
@@ -1928,9 +1898,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e27165889bd793000a098bb966adc4300c312497ea25cf7a690a9f0ac5aa5fc1"
|
||||
checksum = "99636d423fa2ca130fa5acde3059308006d46f98caac629418e53f7ebb1e9999"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"target-lexicon",
|
||||
@@ -1938,9 +1908,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05280526e1dbf6b420062f3ef228b78c0c54ba94e157f5cb724a609d0f2faabc"
|
||||
checksum = "78f9cf92ba9c409279bc3305b5409d90db2d2c22392d443a87df3a1adad59e33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
@@ -1948,27 +1918,27 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c3ce5686aa4d3f63359a5100c62a127c9f15e8398e5fdeb5deef1fed5cd5f44"
|
||||
checksum = "0b999cb1a6ce21f9a6b147dcf1be9ffedf02e0043aec74dc390f3007047cecd9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4cf6faa0cbfb0ed08e89beb8103ae9724eb4750e3a78084ba4017cbe94f3855"
|
||||
checksum = "822ece1c7e1012745607d5cf0bcb2874769f0f7cb34c4cde03b9358eb9ef911a"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"pyo3-build-config",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2017,13 +1987,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
|
||||
dependencies = [
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_core 0.9.3",
|
||||
"zerocopy 0.8.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2052,7 +2021,7 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
"getrandom 0.2.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2092,9 +2061,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.11"
|
||||
version = "0.5.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
|
||||
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
]
|
||||
@@ -2105,7 +2074,7 @@ version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
||||
dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
"getrandom 0.2.16",
|
||||
"libredox",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
@@ -2183,7 +2152,7 @@ dependencies = [
|
||||
"pmutil",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2255,9 +2224,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.5"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"errno",
|
||||
@@ -2346,7 +2315,7 @@ dependencies = [
|
||||
name = "rustpython-compiler"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"rand 0.9.0",
|
||||
"rand 0.9.1",
|
||||
"ruff_python_ast",
|
||||
"ruff_python_parser",
|
||||
"ruff_source_file",
|
||||
@@ -2386,7 +2355,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"rustpython-compiler",
|
||||
"rustpython-derive-impl",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2399,7 +2368,7 @@ dependencies = [
|
||||
"quote",
|
||||
"rustpython-compiler-core",
|
||||
"rustpython-doc",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
"syn-ext",
|
||||
"textwrap",
|
||||
]
|
||||
@@ -2435,7 +2404,7 @@ dependencies = [
|
||||
"is-macro",
|
||||
"lexical-parse-float",
|
||||
"num-traits",
|
||||
"rand 0.9.0",
|
||||
"rand 0.9.1",
|
||||
"rustpython-wtf8",
|
||||
"unic-ucd-category",
|
||||
]
|
||||
@@ -2631,7 +2600,6 @@ name = "rustpython_wasm"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"getrandom 0.2.15",
|
||||
"js-sys",
|
||||
"ruff_python_parser",
|
||||
"rustpython-common",
|
||||
@@ -2732,7 +2700,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2760,9 +2728,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
@@ -2849,7 +2817,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2871,9 +2839,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.100"
|
||||
version = "2.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2888,7 +2856,7 @@ checksum = "b126de4ef6c2a628a68609dd00733766c3b015894698a438ebdf374933fc31d1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2968,7 +2936,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2979,7 +2947,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3320,7 +3288,7 @@ dependencies = [
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -3355,7 +3323,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -3480,7 +3448,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3491,7 +3459,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3693,9 +3661,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.25"
|
||||
version = "0.8.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
|
||||
checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda"
|
||||
|
||||
[[package]]
|
||||
name = "xz2"
|
||||
@@ -3708,42 +3676,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
version = "0.8.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.8.24",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
version = "0.8.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
10
Lib/codeop.py
vendored
10
Lib/codeop.py
vendored
@@ -65,14 +65,10 @@ def _maybe_compile(compiler, source, filename, symbol):
|
||||
try:
|
||||
compiler(source + "\n", filename, symbol)
|
||||
return None
|
||||
except _IncompleteInputError as e:
|
||||
return None
|
||||
except SyntaxError as e:
|
||||
# XXX: RustPython; support multiline definitions in REPL
|
||||
# See also: https://github.com/RustPython/RustPython/pull/5743
|
||||
strerr = str(e)
|
||||
if source.endswith(":") and "expected an indented block" in strerr:
|
||||
return None
|
||||
elif "incomplete input" in str(e):
|
||||
return None
|
||||
pass
|
||||
# fallthrough
|
||||
|
||||
return compiler(source, filename, symbol, incomplete_input=False)
|
||||
|
||||
2
Lib/test/test_baseexception.py
vendored
2
Lib/test/test_baseexception.py
vendored
@@ -83,6 +83,8 @@ class ExceptionClassTests(unittest.TestCase):
|
||||
exc_set = set(e for e in exc_set if not e.startswith('_'))
|
||||
# RUSTPYTHON specific
|
||||
exc_set.discard("JitError")
|
||||
# TODO: RUSTPYTHON; this will be officially introduced in Python 3.15
|
||||
exc_set.discard("IncompleteInputError")
|
||||
self.assertEqual(len(exc_set), 0, "%s not accounted for" % exc_set)
|
||||
|
||||
interface_tests = ("length", "args", "str", "repr")
|
||||
|
||||
4
Lib/test/test_dataclasses.py
vendored
4
Lib/test/test_dataclasses.py
vendored
@@ -2088,8 +2088,6 @@ class TestDocString(unittest.TestCase):
|
||||
|
||||
self.assertDocStrEqual(C.__doc__, "C(x:List[int]=<factory>)")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_docstring_deque_field(self):
|
||||
@dataclass
|
||||
class C:
|
||||
@@ -2097,8 +2095,6 @@ class TestDocString(unittest.TestCase):
|
||||
|
||||
self.assertDocStrEqual(C.__doc__, "C(x:collections.deque)")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_docstring_deque_field_with_default_factory(self):
|
||||
@dataclass
|
||||
class C:
|
||||
|
||||
2
Lib/test/test_httplib.py
vendored
2
Lib/test/test_httplib.py
vendored
@@ -1,3 +1,4 @@
|
||||
import sys
|
||||
import errno
|
||||
from http import client, HTTPStatus
|
||||
import io
|
||||
@@ -1781,6 +1782,7 @@ class HTTPSTest(TestCase):
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.skipIf(sys.platform == 'darwin', 'Occasionally success on macOS')
|
||||
def test_local_unknown_cert(self):
|
||||
# The custom cert isn't known to the default trust bundle
|
||||
import ssl
|
||||
|
||||
3
Lib/test/test_pickle.py
vendored
3
Lib/test/test_pickle.py
vendored
@@ -664,6 +664,9 @@ class CompatPickleTests(unittest.TestCase):
|
||||
BaseExceptionGroup,
|
||||
ExceptionGroup):
|
||||
continue
|
||||
# TODO: RUSTPYTHON: fix name mapping for _IncompleteInputError
|
||||
if exc is _IncompleteInputError:
|
||||
continue
|
||||
if exc is not OSError and issubclass(exc, OSError):
|
||||
self.assertEqual(reverse_mapping('builtins', name),
|
||||
('exceptions', 'OSError'))
|
||||
|
||||
2
Lib/test/test_reprlib.py
vendored
2
Lib/test/test_reprlib.py
vendored
@@ -82,8 +82,6 @@ class ReprTests(unittest.TestCase):
|
||||
expected = repr(t3)[:-2] + "+++)"
|
||||
eq(r3.repr(t3), expected)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_container(self):
|
||||
from array import array
|
||||
from collections import deque
|
||||
|
||||
@@ -226,7 +226,7 @@ To enhance CPython compatibility, try to increase unittest coverage by checking
|
||||
Another approach is to checkout the source code: builtin functions and object
|
||||
methods are often the simplest and easiest way to contribute.
|
||||
|
||||
You can also simply run `uv run python -I whats_left.py` to assist in finding any unimplemented
|
||||
You can also simply run `python -I whats_left.py` to assist in finding any unimplemented
|
||||
method.
|
||||
|
||||
## Compiling to WebAssembly
|
||||
|
||||
@@ -151,7 +151,7 @@ pub fn compile_program(
|
||||
let mut compiler = Compiler::new(opts, source_code, "<module>".to_owned());
|
||||
compiler.compile_program(ast, symbol_table)?;
|
||||
let code = compiler.pop_code_object();
|
||||
trace!("Compilation completed: {:?}", code);
|
||||
trace!("Compilation completed: {code:?}");
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ pub fn compile_program_single(
|
||||
let mut compiler = Compiler::new(opts, source_code, "<module>".to_owned());
|
||||
compiler.compile_program_single(&ast.body, symbol_table)?;
|
||||
let code = compiler.pop_code_object();
|
||||
trace!("Compilation completed: {:?}", code);
|
||||
trace!("Compilation completed: {code:?}");
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ pub fn compile_block_expression(
|
||||
let mut compiler = Compiler::new(opts, source_code, "<module>".to_owned());
|
||||
compiler.compile_block_expr(&ast.body, symbol_table)?;
|
||||
let code = compiler.pop_code_object();
|
||||
trace!("Compilation completed: {:?}", code);
|
||||
trace!("Compilation completed: {code:?}");
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ fn eprint_location(zelf: &Compiler<'_>) {
|
||||
fn unwrap_internal<T>(zelf: &Compiler<'_>, r: InternalResult<T>) -> T {
|
||||
if let Err(ref r_err) = r {
|
||||
eprintln!("=== CODEGEN PANIC INFO ===");
|
||||
eprintln!("This IS an internal error: {}", r_err);
|
||||
eprintln!("This IS an internal error: {r_err}");
|
||||
eprint_location(zelf);
|
||||
eprintln!("=== END PANIC INFO ===");
|
||||
}
|
||||
@@ -671,7 +671,7 @@ impl Compiler<'_> {
|
||||
|
||||
fn compile_statement(&mut self, statement: &Stmt) -> CompileResult<()> {
|
||||
use ruff_python_ast::*;
|
||||
trace!("Compiling {:?}", statement);
|
||||
trace!("Compiling {statement:?}");
|
||||
self.set_source_range(statement.range());
|
||||
|
||||
match &statement {
|
||||
@@ -1907,7 +1907,7 @@ impl Compiler<'_> {
|
||||
|
||||
fn compile_error_forbidden_name(&mut self, name: &str) -> CodegenError {
|
||||
// TODO: make into error (fine for now since it realistically errors out earlier)
|
||||
panic!("Failing due to forbidden name {:?}", name);
|
||||
panic!("Failing due to forbidden name {name:?}");
|
||||
}
|
||||
|
||||
/// Ensures that `pc.fail_pop` has at least `n + 1` entries.
|
||||
@@ -3209,7 +3209,7 @@ impl Compiler<'_> {
|
||||
|
||||
fn compile_expression(&mut self, expression: &Expr) -> CompileResult<()> {
|
||||
use ruff_python_ast::*;
|
||||
trace!("Compiling {:?}", expression);
|
||||
trace!("Compiling {expression:?}");
|
||||
let range = expression.range();
|
||||
self.set_source_range(range);
|
||||
|
||||
@@ -4432,7 +4432,7 @@ pub fn ruff_int_to_bigint(int: &Int) -> Result<BigInt, CodegenErrorType> {
|
||||
fn parse_big_integer(int: &Int) -> Result<BigInt, CodegenErrorType> {
|
||||
// TODO: Improve ruff API
|
||||
// Can we avoid this copy?
|
||||
let s = format!("{}", int);
|
||||
let s = format!("{int}");
|
||||
let mut s = s.as_str();
|
||||
// See: https://peps.python.org/pep-0515/#literal-grammar
|
||||
let radix = match s.get(0..2) {
|
||||
|
||||
@@ -1388,12 +1388,12 @@ impl Instruction {
|
||||
let value = ctx.get_constant(idx.get(arg) as usize);
|
||||
match value.borrow_constant() {
|
||||
BorrowedConstant::Code { code } if expand_code_objects => {
|
||||
write!(f, "{:pad$}({:?}):", op, code)?;
|
||||
write!(f, "{op:pad$}({code:?}):")?;
|
||||
code.display_inner(f, true, level + 1)?;
|
||||
Ok(())
|
||||
}
|
||||
c => {
|
||||
write!(f, "{:pad$}(", op)?;
|
||||
write!(f, "{op:pad$}(")?;
|
||||
c.fmt_display(f)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ pub fn format_fixed(precision: usize, magnitude: f64, case: Case, alternate_form
|
||||
match magnitude {
|
||||
magnitude if magnitude.is_finite() => {
|
||||
let point = decimal_point_or_empty(precision, alternate_form);
|
||||
let precision = std::cmp::min(precision, u16::MAX as usize);
|
||||
format!("{magnitude:.precision$}{point}")
|
||||
}
|
||||
magnitude if magnitude.is_nan() => format_nan(case),
|
||||
|
||||
@@ -25,6 +25,7 @@ pub enum CompileErrorType {
|
||||
pub struct ParseError {
|
||||
#[source]
|
||||
pub error: parser::ParseErrorType,
|
||||
pub raw_location: ruff_text_size::TextRange,
|
||||
pub location: SourceLocation,
|
||||
pub source_path: String,
|
||||
}
|
||||
@@ -48,6 +49,7 @@ impl CompileError {
|
||||
let location = source_code.source_location(error.location.start());
|
||||
Self::Parse(ParseError {
|
||||
error: error.error,
|
||||
raw_location: error.location,
|
||||
location,
|
||||
source_path: source_code.path.to_owned(),
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
""" This script can be used to test the equivalence in parsing between
|
||||
"""This script can be used to test the equivalence in parsing between
|
||||
rustpython and cpython.
|
||||
|
||||
Usage example:
|
||||
@@ -8,76 +8,80 @@ $ cargo run crawl_sourcecode.py crawl_sourcecode.py > rustpython.txt
|
||||
$ diff cpython.txt rustpython.txt
|
||||
"""
|
||||
|
||||
|
||||
import ast
|
||||
import sys
|
||||
import symtable
|
||||
import dis
|
||||
|
||||
filename = sys.argv[1]
|
||||
print('Crawling file:', filename)
|
||||
print("Crawling file:", filename)
|
||||
|
||||
|
||||
with open(filename, 'r') as f:
|
||||
with open(filename, "r") as f:
|
||||
source = f.read()
|
||||
|
||||
t = ast.parse(source)
|
||||
print(t)
|
||||
|
||||
shift = 3
|
||||
|
||||
|
||||
def print_node(node, indent=0):
|
||||
indents = ' ' * indent
|
||||
indents = " " * indent
|
||||
if isinstance(node, ast.AST):
|
||||
lineno = 'row={}'.format(node.lineno) if hasattr(node, 'lineno') else ''
|
||||
lineno = "row={}".format(node.lineno) if hasattr(node, "lineno") else ""
|
||||
print(indents, "NODE", node.__class__.__name__, lineno)
|
||||
for field in node._fields:
|
||||
print(indents,'-', field)
|
||||
print(indents, "-", field)
|
||||
f = getattr(node, field)
|
||||
if isinstance(f, list):
|
||||
for f2 in f:
|
||||
print_node(f2, indent=indent+shift)
|
||||
print_node(f2, indent=indent + shift)
|
||||
else:
|
||||
print_node(f, indent=indent+shift)
|
||||
print_node(f, indent=indent + shift)
|
||||
else:
|
||||
print(indents, 'OBJ', node)
|
||||
print(indents, "OBJ", node)
|
||||
|
||||
|
||||
print_node(t)
|
||||
|
||||
# print(ast.dump(t))
|
||||
flag_names = [
|
||||
'is_referenced',
|
||||
'is_assigned',
|
||||
'is_global',
|
||||
'is_local',
|
||||
'is_parameter',
|
||||
'is_free',
|
||||
"is_referenced",
|
||||
"is_assigned",
|
||||
"is_global",
|
||||
"is_local",
|
||||
"is_parameter",
|
||||
"is_free",
|
||||
]
|
||||
|
||||
|
||||
def print_table(table, indent=0):
|
||||
indents = ' ' * indent
|
||||
print(indents, 'table:', table.get_name())
|
||||
print(indents, ' ', 'name:', table.get_name())
|
||||
print(indents, ' ', 'type:', table.get_type())
|
||||
print(indents, ' ', 'line:', table.get_lineno())
|
||||
print(indents, ' ', 'identifiers:', table.get_identifiers())
|
||||
print(indents, ' ', 'Syms:')
|
||||
indents = " " * indent
|
||||
print(indents, "table:", table.get_name())
|
||||
print(indents, " ", "name:", table.get_name())
|
||||
print(indents, " ", "type:", table.get_type())
|
||||
print(indents, " ", "line:", table.get_lineno())
|
||||
print(indents, " ", "identifiers:", table.get_identifiers())
|
||||
print(indents, " ", "Syms:")
|
||||
for sym in table.get_symbols():
|
||||
flags = []
|
||||
for flag_name in flag_names:
|
||||
func = getattr(sym, flag_name)
|
||||
if func():
|
||||
flags.append(flag_name)
|
||||
print(indents, ' sym:', sym.get_name(), 'flags:', ' '.join(flags))
|
||||
print(indents, " sym:", sym.get_name(), "flags:", " ".join(flags))
|
||||
if table.has_children():
|
||||
print(indents, ' ', 'Child tables:')
|
||||
print(indents, " ", "Child tables:")
|
||||
for child in table.get_children():
|
||||
print_table(child, indent=indent+shift)
|
||||
print_table(child, indent=indent + shift)
|
||||
|
||||
table = symtable.symtable(source, 'a', 'exec')
|
||||
|
||||
table = symtable.symtable(source, "a", "exec")
|
||||
print_table(table)
|
||||
|
||||
print()
|
||||
print('======== dis.dis ========')
|
||||
print("======== dis.dis ========")
|
||||
print()
|
||||
co = compile(source, filename, 'exec')
|
||||
co = compile(source, filename, "exec")
|
||||
dis.dis(co)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
|
||||
|
||||
def foo(x):
|
||||
def bar(z):
|
||||
return z + x
|
||||
|
||||
return bar
|
||||
|
||||
|
||||
f = foo(9)
|
||||
g = foo(10)
|
||||
|
||||
print(f(2))
|
||||
print(g(2))
|
||||
|
||||
|
||||
@@ -1165,8 +1165,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
||||
|
||||
// ----- Merge: Return the final result.
|
||||
self.builder.switch_to_block(merge_block);
|
||||
let final_val = self.builder.block_params(merge_block)[0];
|
||||
final_val
|
||||
self.builder.block_params(merge_block)[0]
|
||||
}
|
||||
|
||||
fn compile_ipow(&mut self, a: Value, b: Value) -> Value {
|
||||
|
||||
@@ -15,7 +15,13 @@ pub enum JitCompileError {
|
||||
#[error("bad bytecode")]
|
||||
BadBytecode,
|
||||
#[error("error while compiling to machine code: {0}")]
|
||||
CraneliftError(#[from] ModuleError),
|
||||
CraneliftError(Box<ModuleError>),
|
||||
}
|
||||
|
||||
impl From<ModuleError> for JitCompileError {
|
||||
fn from(err: ModuleError) -> Self {
|
||||
Self::CraneliftError(Box::new(err))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
|
||||
|
||||
@@ -78,7 +78,7 @@ impl StackMachine {
|
||||
|
||||
pub fn run(&mut self, code: CodeObject) {
|
||||
let mut oparg_state = OpArgState::default();
|
||||
code.instructions.iter().try_for_each(|&word| {
|
||||
let _ = code.instructions.iter().try_for_each(|&word| {
|
||||
let (instruction, arg) = oparg_state.get(word);
|
||||
self.process_instruction(instruction, arg, &code.constants, &code.names)
|
||||
});
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
include = [
|
||||
"examples/**/*.py",
|
||||
"extra_tests/**/*.py",
|
||||
"wasm/**/*.py",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
".*",
|
||||
"Lib",
|
||||
"vm/Lib",
|
||||
"benches",
|
||||
|
||||
@@ -3,18 +3,21 @@ import subprocess
|
||||
|
||||
TARGET = "extra_tests/snippets"
|
||||
|
||||
|
||||
def run_llvm_cov(file_path: str):
|
||||
""" Run cargo llvm-cov on a file. """
|
||||
"""Run cargo llvm-cov on a file."""
|
||||
if file_path.endswith(".py"):
|
||||
command = ["cargo", "llvm-cov", "--no-report", "run", "--", file_path]
|
||||
subprocess.call(command)
|
||||
|
||||
|
||||
def iterate_files(folder: str):
|
||||
""" Iterate over all files in a folder. """
|
||||
"""Iterate over all files in a folder."""
|
||||
for root, _, files in os.walk(folder):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
run_llvm_cov(file_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
iterate_files(TARGET)
|
||||
iterate_files(TARGET)
|
||||
|
||||
@@ -10,21 +10,26 @@ How to use:
|
||||
4. Ensure that there are no unexpected successes in the test.
|
||||
5. Actually fix the test.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import ast
|
||||
import itertools
|
||||
import platform
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Fix test.")
|
||||
parser.add_argument("--path", type=Path, help="Path to test file")
|
||||
parser.add_argument("--force", action="store_true", help="Force modification")
|
||||
parser.add_argument("--platform", action="store_true", help="Platform specific failure")
|
||||
parser.add_argument(
|
||||
"--platform", action="store_true", help="Platform specific failure"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
class Test:
|
||||
name: str = ""
|
||||
path: str = ""
|
||||
@@ -33,6 +38,7 @@ class Test:
|
||||
def __str__(self):
|
||||
return f"Test(name={self.name}, path={self.path}, result={self.result})"
|
||||
|
||||
|
||||
class TestResult:
|
||||
tests_result: str = ""
|
||||
tests = []
|
||||
@@ -52,7 +58,11 @@ def parse_results(result):
|
||||
in_test_results = True
|
||||
elif line.startswith("-----------"):
|
||||
in_test_results = False
|
||||
if in_test_results and not line.startswith("tests") and not line.startswith("["):
|
||||
if (
|
||||
in_test_results
|
||||
and not line.startswith("tests")
|
||||
and not line.startswith("[")
|
||||
):
|
||||
line = line.split(" ")
|
||||
if line != [] and len(line) > 3:
|
||||
test = Test()
|
||||
@@ -67,9 +77,11 @@ def parse_results(result):
|
||||
test_results.tests_result = res
|
||||
return test_results
|
||||
|
||||
|
||||
def path_to_test(path) -> list[str]:
|
||||
return path.split(".")[2:]
|
||||
|
||||
|
||||
def modify_test(file: str, test: list[str], for_platform: bool = False) -> str:
|
||||
a = ast.parse(file)
|
||||
lines = file.splitlines()
|
||||
@@ -84,6 +96,7 @@ def modify_test(file: str, test: list[str], for_platform: bool = False) -> str:
|
||||
break
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def modify_test_v2(file: str, test: list[str], for_platform: bool = False) -> str:
|
||||
a = ast.parse(file)
|
||||
lines = file.splitlines()
|
||||
@@ -101,8 +114,13 @@ def modify_test_v2(file: str, test: list[str], for_platform: bool = False) -> st
|
||||
if fn.name == test[-1]:
|
||||
assert not for_platform
|
||||
indent = " " * fn.col_offset
|
||||
lines.insert(fn.lineno - 1, indent + fixture)
|
||||
lines.insert(fn.lineno - 1, indent + "# TODO: RUSTPYTHON")
|
||||
lines.insert(
|
||||
fn.lineno - 1, indent + fixture
|
||||
)
|
||||
lines.insert(
|
||||
fn.lineno - 1,
|
||||
indent + "# TODO: RUSTPYTHON",
|
||||
)
|
||||
break
|
||||
case ast.FunctionDef():
|
||||
if n.name == test[0] and len(test) == 1:
|
||||
@@ -115,11 +133,17 @@ def modify_test_v2(file: str, test: list[str], for_platform: bool = False) -> st
|
||||
exit()
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def run_test(test_name):
|
||||
print(f"Running test: {test_name}")
|
||||
rustpython_location = "./target/release/rustpython"
|
||||
import subprocess
|
||||
result = subprocess.run([rustpython_location, "-m", "test", "-v", test_name], capture_output=True, text=True)
|
||||
|
||||
result = subprocess.run(
|
||||
[rustpython_location, "-m", "test", "-v", test_name],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
return parse_results(result)
|
||||
|
||||
|
||||
|
||||
@@ -197,12 +197,12 @@ fn run_rustpython(vm: &VirtualMachine, run_mode: RunMode) -> PyResult<()> {
|
||||
}
|
||||
let res = match run_mode {
|
||||
RunMode::Command(command) => {
|
||||
debug!("Running command {}", command);
|
||||
debug!("Running command {command}");
|
||||
vm.run_code_string(scope.clone(), &command, "<stdin>".to_owned())
|
||||
.map(drop)
|
||||
}
|
||||
RunMode::Module(module) => {
|
||||
debug!("Running module {}", module);
|
||||
debug!("Running module {module}");
|
||||
vm.run_module(&module)
|
||||
}
|
||||
RunMode::InstallPip(installer) => install_pip(installer, scope.clone(), vm),
|
||||
|
||||
103
src/shell.rs
103
src/shell.rs
@@ -1,7 +1,8 @@
|
||||
mod helper;
|
||||
|
||||
use rustpython_compiler::{
|
||||
CompileError, ParseError, parser::LexicalErrorType, parser::ParseErrorType,
|
||||
CompileError, ParseError, parser::FStringErrorType, parser::LexicalErrorType,
|
||||
parser::ParseErrorType,
|
||||
};
|
||||
use rustpython_vm::{
|
||||
AsObject, PyResult, VirtualMachine,
|
||||
@@ -14,7 +15,8 @@ use rustpython_vm::{
|
||||
enum ShellExecResult {
|
||||
Ok,
|
||||
PyErr(PyBaseExceptionRef),
|
||||
Continue,
|
||||
ContinueBlock,
|
||||
ContinueLine,
|
||||
}
|
||||
|
||||
fn shell_exec(
|
||||
@@ -22,11 +24,17 @@ fn shell_exec(
|
||||
source: &str,
|
||||
scope: Scope,
|
||||
empty_line_given: bool,
|
||||
continuing: bool,
|
||||
continuing_block: bool,
|
||||
) -> ShellExecResult {
|
||||
// compiling expects only UNIX style line endings, and will replace windows line endings
|
||||
// internally. Since we might need to analyze the source to determine if an error could be
|
||||
// resolved by future input, we need the location from the error to match the source code that
|
||||
// was actually compiled.
|
||||
#[cfg(windows)]
|
||||
let source = &source.replace("\r\n", "\n");
|
||||
match vm.compile(source, compiler::Mode::Single, "<stdin>".to_owned()) {
|
||||
Ok(code) => {
|
||||
if empty_line_given || !continuing {
|
||||
if empty_line_given || !continuing_block {
|
||||
// We want to execute the full code
|
||||
match vm.run_code_obj(code, scope) {
|
||||
Ok(_val) => ShellExecResult::Ok,
|
||||
@@ -40,8 +48,32 @@ fn shell_exec(
|
||||
Err(CompileError::Parse(ParseError {
|
||||
error: ParseErrorType::Lexical(LexicalErrorType::Eof),
|
||||
..
|
||||
})) => ShellExecResult::Continue,
|
||||
})) => ShellExecResult::ContinueLine,
|
||||
Err(CompileError::Parse(ParseError {
|
||||
error:
|
||||
ParseErrorType::Lexical(LexicalErrorType::FStringError(
|
||||
FStringErrorType::UnterminatedTripleQuotedString,
|
||||
)),
|
||||
..
|
||||
})) => ShellExecResult::ContinueLine,
|
||||
Err(err) => {
|
||||
// Check if the error is from an unclosed triple quoted string (which should always
|
||||
// continue)
|
||||
if let CompileError::Parse(ParseError {
|
||||
error: ParseErrorType::Lexical(LexicalErrorType::UnclosedStringError),
|
||||
raw_location,
|
||||
..
|
||||
}) = err
|
||||
{
|
||||
let loc = raw_location.start().to_usize();
|
||||
let mut iter = source.chars();
|
||||
if let Some(quote) = iter.nth(loc) {
|
||||
if iter.next() == Some(quote) && iter.next() == Some(quote) {
|
||||
return ShellExecResult::ContinueLine;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// bad_error == true if we are handling an error that should be thrown even if we are continuing
|
||||
// if its an indentation error, set to true if we are continuing and the error is on column 0,
|
||||
// since indentations errors on columns other than 0 should be ignored.
|
||||
@@ -50,10 +82,12 @@ fn shell_exec(
|
||||
let bad_error = match err {
|
||||
CompileError::Parse(ref p) => {
|
||||
match &p.error {
|
||||
ParseErrorType::Lexical(LexicalErrorType::IndentationError) => continuing, // && p.location.is_some()
|
||||
ParseErrorType::Lexical(LexicalErrorType::IndentationError) => {
|
||||
continuing_block
|
||||
} // && p.location.is_some()
|
||||
ParseErrorType::OtherError(msg) => {
|
||||
if msg.starts_with("Expected an indented block") {
|
||||
continuing
|
||||
continuing_block
|
||||
} else {
|
||||
true
|
||||
}
|
||||
@@ -68,7 +102,7 @@ fn shell_exec(
|
||||
if empty_line_given || bad_error {
|
||||
ShellExecResult::PyErr(vm.new_syntax_error(&err, Some(source)))
|
||||
} else {
|
||||
ShellExecResult::Continue
|
||||
ShellExecResult::ContinueBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,10 +127,19 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
|
||||
println!("No previous history.");
|
||||
}
|
||||
|
||||
let mut continuing = false;
|
||||
// We might either be waiting to know if a block is complete, or waiting to know if a multiline
|
||||
// statement is complete. In the former case, we need to ensure that we read one extra new line
|
||||
// to know that the block is complete. In the latter, we can execute as soon as the statement is
|
||||
// valid.
|
||||
let mut continuing_block = false;
|
||||
let mut continuing_line = false;
|
||||
|
||||
loop {
|
||||
let prompt_name = if continuing { "ps2" } else { "ps1" };
|
||||
let prompt_name = if continuing_block || continuing_line {
|
||||
"ps2"
|
||||
} else {
|
||||
"ps1"
|
||||
};
|
||||
let prompt = vm
|
||||
.sys_module
|
||||
.get_attr(prompt_name, vm)
|
||||
@@ -105,9 +148,12 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
|
||||
Ok(ref s) => s.as_str(),
|
||||
Err(_) => "",
|
||||
};
|
||||
|
||||
continuing_line = false;
|
||||
let result = match repl.readline(prompt) {
|
||||
ReadlineResult::Line(line) => {
|
||||
debug!("You entered {:?}", line);
|
||||
#[cfg(debug_assertions)]
|
||||
debug!("You entered {line:?}");
|
||||
|
||||
repl.add_history_entry(line.trim_end()).unwrap();
|
||||
|
||||
@@ -120,39 +166,44 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
|
||||
}
|
||||
full_input.push('\n');
|
||||
|
||||
match shell_exec(vm, &full_input, scope.clone(), empty_line_given, continuing) {
|
||||
match shell_exec(
|
||||
vm,
|
||||
&full_input,
|
||||
scope.clone(),
|
||||
empty_line_given,
|
||||
continuing_block,
|
||||
) {
|
||||
ShellExecResult::Ok => {
|
||||
if continuing {
|
||||
if continuing_block {
|
||||
if empty_line_given {
|
||||
// We should be exiting continue mode
|
||||
continuing = false;
|
||||
// We should exit continue mode since the block successfully executed
|
||||
continuing_block = false;
|
||||
full_input.clear();
|
||||
Ok(())
|
||||
} else {
|
||||
// We should stay in continue mode
|
||||
continuing = true;
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
// We aren't in continue mode so proceed normally
|
||||
continuing = false;
|
||||
full_input.clear();
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
ShellExecResult::Continue => {
|
||||
continuing = true;
|
||||
// Continue, but don't change the mode
|
||||
ShellExecResult::ContinueLine => {
|
||||
continuing_line = true;
|
||||
Ok(())
|
||||
}
|
||||
ShellExecResult::ContinueBlock => {
|
||||
continuing_block = true;
|
||||
Ok(())
|
||||
}
|
||||
ShellExecResult::PyErr(err) => {
|
||||
continuing = false;
|
||||
continuing_block = false;
|
||||
full_input.clear();
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
ReadlineResult::Interrupt => {
|
||||
continuing = false;
|
||||
continuing_block = false;
|
||||
full_input.clear();
|
||||
let keyboard_interrupt =
|
||||
vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.to_owned());
|
||||
|
||||
@@ -756,8 +756,7 @@ impl ToPyException for Base64DecodeError {
|
||||
InvalidLastSymbol(_, PAD) => "Excess data after padding".to_owned(),
|
||||
InvalidLastSymbol(length, _) => {
|
||||
format!(
|
||||
"Invalid base64-encoded string: number of data characters {} cannot be 1 more than a multiple of 4",
|
||||
length
|
||||
"Invalid base64-encoded string: number of data characters {length} cannot be 1 more than a multiple of 4"
|
||||
)
|
||||
}
|
||||
// TODO: clean up errors
|
||||
|
||||
@@ -346,13 +346,9 @@ mod _csv {
|
||||
if !rest.args.is_empty() {
|
||||
let arg_len = rest.args.len();
|
||||
if arg_len != 1 {
|
||||
return Err(vm.new_type_error(
|
||||
format!(
|
||||
"field_size_limit() takes at most 1 argument ({} given)",
|
||||
arg_len
|
||||
)
|
||||
.to_string(),
|
||||
));
|
||||
return Err(vm.new_type_error(format!(
|
||||
"field_size_limit() takes at most 1 argument ({arg_len} given)"
|
||||
)));
|
||||
}
|
||||
let Ok(new_size) = rest.args.first().unwrap().try_int(vm) else {
|
||||
return Err(vm.new_type_error("limit must be an integer".to_string()));
|
||||
@@ -701,7 +697,7 @@ mod _csv {
|
||||
if let Some(dialect) = g.get(name) {
|
||||
Ok(self.update_py_dialect(*dialect))
|
||||
} else {
|
||||
Err(new_csv_error(vm, format!("{} is not registered.", name)))
|
||||
Err(new_csv_error(vm, format!("{name} is not registered.")))
|
||||
}
|
||||
// TODO
|
||||
// Maybe need to update the obj from HashMap
|
||||
|
||||
@@ -363,7 +363,7 @@ impl FormatSpec {
|
||||
// Loop over all opcodes:
|
||||
for code in &self.codes {
|
||||
buffer = &mut buffer[code.pre_padding..];
|
||||
debug!("code: {:?}", code);
|
||||
debug!("code: {code:?}");
|
||||
match code.code {
|
||||
FormatType::Str => {
|
||||
let (buf, rest) = buffer.split_at_mut(code.repeat);
|
||||
@@ -407,7 +407,7 @@ impl FormatSpec {
|
||||
let mut items = Vec::with_capacity(self.arg_count);
|
||||
for code in &self.codes {
|
||||
data = &data[code.pre_padding..];
|
||||
debug!("unpack code: {:?}", code);
|
||||
debug!("unpack code: {code:?}");
|
||||
match code.code {
|
||||
FormatType::Pad => {
|
||||
data = &data[code.repeat..];
|
||||
|
||||
@@ -66,10 +66,9 @@ impl PyObjectRef {
|
||||
warnings::warn(
|
||||
vm.ctx.exceptions.deprecation_warning,
|
||||
format!(
|
||||
"__complex__ returned non-complex (type {}). \
|
||||
"__complex__ returned non-complex (type {ret_class}). \
|
||||
The ability to return an instance of a strict subclass of complex \
|
||||
is deprecated, and may be removed in a future version of Python.",
|
||||
ret_class
|
||||
is deprecated, and may be removed in a future version of Python."
|
||||
),
|
||||
1,
|
||||
vm,
|
||||
|
||||
@@ -53,14 +53,12 @@ impl Constructor for PyBaseObject {
|
||||
0 => {}
|
||||
1 => {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"class {} without an implementation for abstract method '{}'",
|
||||
name, methods
|
||||
"class {name} without an implementation for abstract method '{methods}'"
|
||||
)));
|
||||
}
|
||||
2.. => {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"class {} without an implementation for abstract methods '{}'",
|
||||
name, methods
|
||||
"class {name} without an implementation for abstract methods '{methods}'"
|
||||
)));
|
||||
}
|
||||
// TODO: remove `allow` when redox build doesn't complain about it
|
||||
|
||||
@@ -132,8 +132,7 @@ impl PyProperty {
|
||||
let func_args_len = func_args.args.len();
|
||||
let (_owner, name): (PyObjectRef, PyObjectRef) = func_args.bind(vm).map_err(|_e| {
|
||||
vm.new_type_error(format!(
|
||||
"__set_name__() takes 2 positional arguments but {} were given",
|
||||
func_args_len
|
||||
"__set_name__() takes 2 positional arguments but {func_args_len} were given"
|
||||
))
|
||||
})?;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// cspell:ignore cmeth
|
||||
/*! Python `super` class.
|
||||
|
||||
See also [CPython source code.](https://github.com/python/cpython/blob/50b48572d9a90c5bb36e2bef6179548ea927a35a/Objects/typeobject.c#L7663)
|
||||
@@ -125,8 +126,8 @@ impl Initializer for PySuper {
|
||||
(typ, obj)
|
||||
};
|
||||
|
||||
let mut inner = PySuperInner::new(typ, obj, vm)?;
|
||||
std::mem::swap(&mut inner, &mut zelf.inner.write());
|
||||
let inner = PySuperInner::new(typ, obj, vm)?;
|
||||
*zelf.inner.write() = inner;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ impl StandardEncoding {
|
||||
match encoding {
|
||||
"be" => Some(Self::Utf32Be),
|
||||
"le" => Some(Self::Utf32Le),
|
||||
_ => return None,
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
@@ -1116,7 +1116,7 @@ fn replace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(PyObjectRe
|
||||
let replace = replacement_char.repeat(range.end - range.start);
|
||||
Ok((replace.to_pyobject(vm), range.end))
|
||||
} else {
|
||||
return Err(bad_err_type(err, vm));
|
||||
Err(bad_err_type(err, vm))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,3 +49,10 @@ impl crate::convert::ToPyException for (CompileError, Option<&str>) {
|
||||
vm.new_syntax_error(&self.0, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "parser", feature = "codegen"))]
|
||||
impl crate::convert::ToPyException for (CompileError, Option<&str>, bool) {
|
||||
fn to_pyexception(&self, vm: &crate::VirtualMachine) -> crate::builtins::PyBaseExceptionRef {
|
||||
vm.new_syntax_error_maybe_incomplete(&self.0, self.1, self.2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{PyResult, VirtualMachine, compiler, scope::Scope};
|
||||
pub fn eval(vm: &VirtualMachine, source: &str, scope: Scope, source_path: &str) -> PyResult {
|
||||
match vm.compile(source, compiler::Mode::Eval, source_path.to_owned()) {
|
||||
Ok(bytecode) => {
|
||||
debug!("Code object: {:?}", bytecode);
|
||||
debug!("Code object: {bytecode:?}");
|
||||
vm.run_code_obj(bytecode, scope)
|
||||
}
|
||||
Err(err) => Err(vm.new_syntax_error(&err, Some(source))),
|
||||
|
||||
@@ -206,7 +206,7 @@ impl VirtualMachine {
|
||||
lineno
|
||||
)?;
|
||||
} else if let Some(filename) = maybe_filename {
|
||||
filename_suffix = format!(" ({})", filename);
|
||||
filename_suffix = format!(" ({filename})");
|
||||
}
|
||||
|
||||
if let Some(text) = maybe_text {
|
||||
@@ -215,7 +215,7 @@ impl VirtualMachine {
|
||||
let l_text = r_text.trim_start_matches([' ', '\n', '\x0c']); // \x0c is \f
|
||||
let spaces = (r_text.len() - l_text.len()) as isize;
|
||||
|
||||
writeln!(output, " {}", l_text)?;
|
||||
writeln!(output, " {l_text}")?;
|
||||
|
||||
let maybe_offset: Option<isize> =
|
||||
getattr("offset").and_then(|obj| obj.try_to_value::<isize>(vm).ok());
|
||||
@@ -495,6 +495,7 @@ pub struct ExceptionZoo {
|
||||
pub not_implemented_error: &'static Py<PyType>,
|
||||
pub recursion_error: &'static Py<PyType>,
|
||||
pub syntax_error: &'static Py<PyType>,
|
||||
pub incomplete_input_error: &'static Py<PyType>,
|
||||
pub indentation_error: &'static Py<PyType>,
|
||||
pub tab_error: &'static Py<PyType>,
|
||||
pub system_error: &'static Py<PyType>,
|
||||
@@ -743,6 +744,7 @@ impl ExceptionZoo {
|
||||
let recursion_error = PyRecursionError::init_builtin_type();
|
||||
|
||||
let syntax_error = PySyntaxError::init_builtin_type();
|
||||
let incomplete_input_error = PyIncompleteInputError::init_builtin_type();
|
||||
let indentation_error = PyIndentationError::init_builtin_type();
|
||||
let tab_error = PyTabError::init_builtin_type();
|
||||
|
||||
@@ -817,6 +819,7 @@ impl ExceptionZoo {
|
||||
not_implemented_error,
|
||||
recursion_error,
|
||||
syntax_error,
|
||||
incomplete_input_error,
|
||||
indentation_error,
|
||||
tab_error,
|
||||
system_error,
|
||||
@@ -965,6 +968,7 @@ impl ExceptionZoo {
|
||||
"end_offset" => ctx.none(),
|
||||
"text" => ctx.none(),
|
||||
});
|
||||
extend_exception!(PyIncompleteInputError, ctx, excs.incomplete_input_error);
|
||||
extend_exception!(PyIndentationError, ctx, excs.indentation_error);
|
||||
extend_exception!(PyTabError, ctx, excs.tab_error);
|
||||
|
||||
@@ -1611,7 +1615,7 @@ pub(super) mod types {
|
||||
format!("{} ({}, line {})", msg, basename(filename.as_str()), lineno)
|
||||
}
|
||||
(Some(lineno), None) => {
|
||||
format!("{} (line {})", msg, lineno)
|
||||
format!("{msg} (line {lineno})")
|
||||
}
|
||||
(None, Some(filename)) => {
|
||||
format!("{} ({})", msg, basename(filename.as_str()))
|
||||
@@ -1623,6 +1627,28 @@ pub(super) mod types {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyexception(
|
||||
name = "_IncompleteInputError",
|
||||
base = "PySyntaxError",
|
||||
ctx = "incomplete_input_error"
|
||||
)]
|
||||
#[derive(Debug)]
|
||||
pub struct PyIncompleteInputError {}
|
||||
|
||||
#[pyexception]
|
||||
impl PyIncompleteInputError {
|
||||
#[pyslot]
|
||||
#[pymethod(name = "__init__")]
|
||||
pub(crate) fn slot_init(
|
||||
zelf: PyObjectRef,
|
||||
_args: FuncArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
zelf.set_attr("name", vm.ctx.new_str("SyntaxError"), vm)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[pyexception(name, base = "PySyntaxError", ctx = "indentation_error", impl)]
|
||||
#[derive(Debug)]
|
||||
pub struct PyIndentationError {}
|
||||
|
||||
@@ -1667,7 +1667,8 @@ impl ExecutingFrame<'_> {
|
||||
.topmost_exception()
|
||||
.ok_or_else(|| vm.new_runtime_error("No active exception to reraise".to_owned()))?,
|
||||
};
|
||||
debug!("Exception raised: {:?} with cause: {:?}", exception, cause);
|
||||
#[cfg(debug_assertions)]
|
||||
debug!("Exception raised: {exception:?} with cause: {cause:?}");
|
||||
if let Some(cause) = cause {
|
||||
exception.set_cause(cause);
|
||||
}
|
||||
|
||||
@@ -51,8 +51,7 @@ impl PyObject {
|
||||
Err(err) => return err,
|
||||
};
|
||||
vm.new_value_error(format!(
|
||||
"invalid literal for int() with base {}: {}",
|
||||
base, repr,
|
||||
"invalid literal for int() with base {base}: {repr}",
|
||||
))
|
||||
})?;
|
||||
Ok(PyInt::from(i).into_ref(&vm.ctx))
|
||||
@@ -475,10 +474,9 @@ impl PyNumber<'_> {
|
||||
warnings::warn(
|
||||
vm.ctx.exceptions.deprecation_warning,
|
||||
format!(
|
||||
"__int__ returned non-int (type {}). \
|
||||
"__int__ returned non-int (type {ret_class}). \
|
||||
The ability to return an instance of a strict subclass of int \
|
||||
is deprecated, and may be removed in a future version of Python.",
|
||||
ret_class
|
||||
is deprecated, and may be removed in a future version of Python."
|
||||
),
|
||||
1,
|
||||
vm,
|
||||
@@ -509,10 +507,9 @@ impl PyNumber<'_> {
|
||||
warnings::warn(
|
||||
vm.ctx.exceptions.deprecation_warning,
|
||||
format!(
|
||||
"__index__ returned non-int (type {}). \
|
||||
"__index__ returned non-int (type {ret_class}). \
|
||||
The ability to return an instance of a strict subclass of int \
|
||||
is deprecated, and may be removed in a future version of Python.",
|
||||
ret_class
|
||||
is deprecated, and may be removed in a future version of Python."
|
||||
),
|
||||
1,
|
||||
vm,
|
||||
@@ -543,10 +540,9 @@ impl PyNumber<'_> {
|
||||
warnings::warn(
|
||||
vm.ctx.exceptions.deprecation_warning,
|
||||
format!(
|
||||
"__float__ returned non-float (type {}). \
|
||||
"__float__ returned non-float (type {ret_class}). \
|
||||
The ability to return an instance of a strict subclass of float \
|
||||
is deprecated, and may be removed in a future version of Python.",
|
||||
ret_class
|
||||
is deprecated, and may be removed in a future version of Python."
|
||||
),
|
||||
1,
|
||||
vm,
|
||||
|
||||
@@ -245,6 +245,7 @@ pub(crate) fn parse(
|
||||
let top = parser::parse(source, mode.into())
|
||||
.map_err(|parse_error| ParseError {
|
||||
error: parse_error.error,
|
||||
raw_location: parse_error.location,
|
||||
location: text_range_to_source_range(&source_code, parse_error.location)
|
||||
.start
|
||||
.to_source_location(),
|
||||
@@ -295,8 +296,8 @@ pub const PY_COMPILE_FLAG_AST_ONLY: i32 = 0x0400;
|
||||
// The following flags match the values from Include/cpython/compile.h
|
||||
// Caveat emptor: These flags are undocumented on purpose and depending
|
||||
// on their effect outside the standard library is **unsupported**.
|
||||
const PY_CF_DONT_IMPLY_DEDENT: i32 = 0x200;
|
||||
const PY_CF_ALLOW_INCOMPLETE_INPUT: i32 = 0x4000;
|
||||
pub const PY_CF_DONT_IMPLY_DEDENT: i32 = 0x200;
|
||||
pub const PY_CF_ALLOW_INCOMPLETE_INPUT: i32 = 0x4000;
|
||||
|
||||
// __future__ flags - sync with Lib/__future__.py
|
||||
// TODO: These flags aren't being used in rust code
|
||||
|
||||
@@ -186,6 +186,8 @@ mod builtins {
|
||||
return Err(vm.new_value_error("compile() unrecognized flags".to_owned()));
|
||||
}
|
||||
|
||||
let allow_incomplete = !(flags & ast::PY_CF_ALLOW_INCOMPLETE_INPUT).is_zero();
|
||||
|
||||
if (flags & ast::PY_COMPILE_FLAG_AST_ONLY).is_zero() {
|
||||
#[cfg(not(feature = "compiler"))]
|
||||
{
|
||||
@@ -207,14 +209,17 @@ mod builtins {
|
||||
args.filename.to_string_lossy().into_owned(),
|
||||
opts,
|
||||
)
|
||||
.map_err(|err| (err, Some(source)).to_pyexception(vm))?;
|
||||
.map_err(|err| {
|
||||
(err, Some(source), allow_incomplete).to_pyexception(vm)
|
||||
})?;
|
||||
Ok(code.into())
|
||||
}
|
||||
} else {
|
||||
let mode = mode_str
|
||||
.parse::<parser::Mode>()
|
||||
.map_err(|err| vm.new_value_error(err.to_string()))?;
|
||||
ast::parse(vm, source, mode).map_err(|e| (e, Some(source)).to_pyexception(vm))
|
||||
ast::parse(vm, source, mode)
|
||||
.map_err(|e| (e, Some(source), allow_incomplete).to_pyexception(vm))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1056,6 +1061,7 @@ pub fn init_module(vm: &VirtualMachine, module: &Py<PyModule>) {
|
||||
"NotImplementedError" => ctx.exceptions.not_implemented_error.to_owned(),
|
||||
"RecursionError" => ctx.exceptions.recursion_error.to_owned(),
|
||||
"SyntaxError" => ctx.exceptions.syntax_error.to_owned(),
|
||||
"_IncompleteInputError" => ctx.exceptions.incomplete_input_error.to_owned(),
|
||||
"IndentationError" => ctx.exceptions.indentation_error.to_owned(),
|
||||
"TabError" => ctx.exceptions.tab_error.to_owned(),
|
||||
"SystemError" => ctx.exceptions.system_error.to_owned(),
|
||||
|
||||
@@ -27,7 +27,7 @@ mod _collections {
|
||||
use std::collections::VecDeque;
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "deque", unhashable = true)]
|
||||
#[pyclass(module = "collections", name = "deque", unhashable = true)]
|
||||
#[derive(Debug, Default, PyPayload)]
|
||||
struct PyDeque {
|
||||
deque: PyRwLock<VecDeque<PyObjectRef>>,
|
||||
|
||||
@@ -251,7 +251,7 @@ impl PyCSimple {
|
||||
#[pyclassmethod]
|
||||
fn repeat(cls: PyTypeRef, n: isize, vm: &VirtualMachine) -> PyResult {
|
||||
if n < 0 {
|
||||
return Err(vm.new_value_error(format!("Array length must be >= 0, not {}", n)));
|
||||
return Err(vm.new_value_error(format!("Array length must be >= 0, not {n}")));
|
||||
}
|
||||
Ok(PyCArrayType {
|
||||
inner: PyCArray {
|
||||
|
||||
@@ -13,6 +13,7 @@ use libffi::middle::{Arg, Cif, CodePtr, Type};
|
||||
use libloading::Symbol;
|
||||
use num_traits::ToPrimitive;
|
||||
use rustpython_common::lock::PyRwLock;
|
||||
use std::ffi::CString;
|
||||
use std::fmt::Debug;
|
||||
|
||||
// https://github.com/python/cpython/blob/4f8bb3947cfbc20f970ff9d9531e1132a9e95396/Modules/_ctypes/callproc.c#L15
|
||||
@@ -77,10 +78,11 @@ impl Function {
|
||||
}
|
||||
})
|
||||
.collect::<PyResult<Vec<Type>>>()?;
|
||||
let terminated = format!("{}\0", function);
|
||||
let c_function_name = CString::new(function)
|
||||
.map_err(|_| vm.new_value_error("Function name contains null bytes".to_string()))?;
|
||||
let pointer: Symbol<'_, FP> = unsafe {
|
||||
library
|
||||
.get(terminated.as_bytes())
|
||||
.get(c_function_name.as_bytes())
|
||||
.map_err(|err| err.to_string())
|
||||
.map_err(|err| vm.new_attribute_error(err))?
|
||||
};
|
||||
|
||||
@@ -53,7 +53,7 @@ impl GetAttr for PyCStructure {
|
||||
let data = zelf.data.read();
|
||||
match data.get(&name) {
|
||||
Some(value) => Ok(value.clone()),
|
||||
None => Err(vm.new_attribute_error(format!("No attribute named {}", name))),
|
||||
None => Err(vm.new_attribute_error(format!("No attribute named {name}"))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +259,9 @@ mod _io {
|
||||
}
|
||||
|
||||
fn write(&mut self, data: &[u8]) -> Option<u64> {
|
||||
if data.is_empty() {
|
||||
return Some(0);
|
||||
}
|
||||
let length = data.len();
|
||||
self.cursor.write_all(data).ok()?;
|
||||
Some(length as u64)
|
||||
@@ -1172,7 +1175,7 @@ mod _io {
|
||||
vm.call_method(self.raw.as_ref().unwrap(), "readinto", (mem_obj.clone(),));
|
||||
|
||||
mem_obj.release();
|
||||
std::mem::swap(v, &mut read_buf.take());
|
||||
*v = read_buf.take();
|
||||
|
||||
res?
|
||||
}
|
||||
|
||||
@@ -1989,7 +1989,7 @@ pub mod module {
|
||||
let pathname = vm.ctx.new_dict();
|
||||
for variant in PathconfVar::iter() {
|
||||
// get the name of variant as a string to use as the dictionary key
|
||||
let key = vm.ctx.new_str(format!("{:?}", variant));
|
||||
let key = vm.ctx.new_str(format!("{variant:?}"));
|
||||
// get the enum from the string and convert it to an integer for the dictionary value
|
||||
let value = vm.ctx.new_int(variant as u8);
|
||||
pathname
|
||||
@@ -2185,7 +2185,7 @@ pub mod module {
|
||||
let names = vm.ctx.new_dict();
|
||||
for variant in SysconfVar::iter() {
|
||||
// get the name of variant as a string to use as the dictionary key
|
||||
let key = vm.ctx.new_str(format!("{:?}", variant));
|
||||
let key = vm.ctx.new_str(format!("{variant:?}"));
|
||||
// get the enum from the string and convert it to an integer for the dictionary value
|
||||
let value = vm.ctx.new_int(variant as u8);
|
||||
names
|
||||
|
||||
@@ -317,9 +317,9 @@ mod sys {
|
||||
let mut source = String::new();
|
||||
handle
|
||||
.read_to_string(&mut source)
|
||||
.map_err(|e| vm.new_os_error(format!("Error reading from stdin: {}", e)))?;
|
||||
.map_err(|e| vm.new_os_error(format!("Error reading from stdin: {e}")))?;
|
||||
vm.compile(&source, crate::compiler::Mode::Single, "<stdin>".to_owned())
|
||||
.map_err(|e| vm.new_os_error(format!("Error running stdin: {}", e)))?;
|
||||
.map_err(|e| vm.new_os_error(format!("Error running stdin: {e}")))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -723,7 +723,7 @@ mod sys {
|
||||
vm.state.int_max_str_digits.store(maxdigits);
|
||||
Ok(())
|
||||
} else {
|
||||
let error = format!("maxdigits must be 0 or larger than {:?}", threshold);
|
||||
let error = format!("maxdigits must be 0 or larger than {threshold:?}");
|
||||
Err(vm.new_value_error(error))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ impl VirtualMachine {
|
||||
self.run_code_string(scope, &source, path.to_owned())?;
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed reading file '{}': {}", path, err);
|
||||
error!("Failed reading file '{path}': {err}");
|
||||
// TODO: Need to change to ExitCode or Termination
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
@@ -320,10 +320,11 @@ impl VirtualMachine {
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "parser", feature = "compiler"))]
|
||||
pub fn new_syntax_error(
|
||||
pub fn new_syntax_error_maybe_incomplete(
|
||||
&self,
|
||||
error: &crate::compiler::CompileError,
|
||||
source: Option<&str>,
|
||||
allow_incomplete: bool,
|
||||
) -> PyBaseExceptionRef {
|
||||
use crate::source::SourceLocation;
|
||||
|
||||
@@ -343,12 +344,102 @@ impl VirtualMachine {
|
||||
..
|
||||
}) => self.ctx.exceptions.indentation_error,
|
||||
#[cfg(feature = "parser")]
|
||||
crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
|
||||
error:
|
||||
ruff_python_parser::ParseErrorType::Lexical(
|
||||
ruff_python_parser::LexicalErrorType::Eof,
|
||||
),
|
||||
..
|
||||
}) => {
|
||||
if allow_incomplete {
|
||||
self.ctx.exceptions.incomplete_input_error
|
||||
} else {
|
||||
self.ctx.exceptions.syntax_error
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "parser")]
|
||||
crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
|
||||
error:
|
||||
ruff_python_parser::ParseErrorType::Lexical(
|
||||
ruff_python_parser::LexicalErrorType::FStringError(
|
||||
ruff_python_parser::FStringErrorType::UnterminatedTripleQuotedString,
|
||||
),
|
||||
),
|
||||
..
|
||||
}) => {
|
||||
if allow_incomplete {
|
||||
self.ctx.exceptions.incomplete_input_error
|
||||
} else {
|
||||
self.ctx.exceptions.syntax_error
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "parser")]
|
||||
crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
|
||||
error:
|
||||
ruff_python_parser::ParseErrorType::Lexical(
|
||||
ruff_python_parser::LexicalErrorType::UnclosedStringError,
|
||||
),
|
||||
raw_location,
|
||||
..
|
||||
}) => {
|
||||
if allow_incomplete {
|
||||
let mut is_incomplete = false;
|
||||
|
||||
if let Some(source) = source {
|
||||
let loc = raw_location.start().to_usize();
|
||||
let mut iter = source.chars();
|
||||
if let Some(quote) = iter.nth(loc) {
|
||||
if iter.next() == Some(quote) && iter.next() == Some(quote) {
|
||||
is_incomplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if is_incomplete {
|
||||
self.ctx.exceptions.incomplete_input_error
|
||||
} else {
|
||||
self.ctx.exceptions.syntax_error
|
||||
}
|
||||
} else {
|
||||
self.ctx.exceptions.syntax_error
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "parser")]
|
||||
crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
|
||||
error: ruff_python_parser::ParseErrorType::OtherError(s),
|
||||
raw_location,
|
||||
..
|
||||
}) => {
|
||||
if s.starts_with("Expected an indented block after") {
|
||||
self.ctx.exceptions.indentation_error
|
||||
if allow_incomplete {
|
||||
// Check that all chars in the error are whitespace, if so, the source is
|
||||
// incomplete. Otherwise, we've found code that might violates
|
||||
// indentation rules.
|
||||
let mut is_incomplete = true;
|
||||
if let Some(source) = source {
|
||||
let start = raw_location.start().to_usize();
|
||||
let end = raw_location.end().to_usize();
|
||||
let mut iter = source.chars();
|
||||
iter.nth(start);
|
||||
for _ in start..end {
|
||||
if let Some(c) = iter.next() {
|
||||
if !c.is_ascii_whitespace() {
|
||||
is_incomplete = false;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if is_incomplete {
|
||||
self.ctx.exceptions.incomplete_input_error
|
||||
} else {
|
||||
self.ctx.exceptions.indentation_error
|
||||
}
|
||||
} else {
|
||||
self.ctx.exceptions.indentation_error
|
||||
}
|
||||
} else {
|
||||
self.ctx.exceptions.syntax_error
|
||||
}
|
||||
@@ -410,6 +501,15 @@ impl VirtualMachine {
|
||||
syntax_error
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "parser", feature = "compiler"))]
|
||||
pub fn new_syntax_error(
|
||||
&self,
|
||||
error: &crate::compiler::CompileError,
|
||||
source: Option<&str>,
|
||||
) -> PyBaseExceptionRef {
|
||||
self.new_syntax_error_maybe_incomplete(error, source, false)
|
||||
}
|
||||
|
||||
pub fn new_import_error(&self, msg: String, name: PyStrRef) -> PyBaseExceptionRef {
|
||||
let import_error = self.ctx.exceptions.import_error.to_owned();
|
||||
let exc = self.new_exception_msg(import_error, msg);
|
||||
|
||||
@@ -10,6 +10,7 @@ del m
|
||||
|
||||
assert re._constants.MAGIC == sre_engine_magic
|
||||
|
||||
|
||||
class CompiledPattern:
|
||||
@classmethod
|
||||
def compile(cls, pattern, flags=0):
|
||||
@@ -21,40 +22,50 @@ class CompiledPattern:
|
||||
self.flags = re.RegexFlag(flags | p.state.flags)
|
||||
return self
|
||||
|
||||
|
||||
for k, v in re.RegexFlag.__members__.items():
|
||||
setattr(CompiledPattern, k, v)
|
||||
|
||||
|
||||
class EscapeRustStr:
|
||||
hardcoded = {
|
||||
ord('\r'): '\\r',
|
||||
ord('\t'): '\\t',
|
||||
ord('\r'): '\\r',
|
||||
ord('\n'): '\\n',
|
||||
ord('\\'): '\\\\',
|
||||
ord('\''): '\\\'',
|
||||
ord('\"'): '\\\"',
|
||||
ord("\r"): "\\r",
|
||||
ord("\t"): "\\t",
|
||||
ord("\r"): "\\r",
|
||||
ord("\n"): "\\n",
|
||||
ord("\\"): "\\\\",
|
||||
ord("'"): "\\'",
|
||||
ord('"'): '\\"',
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def __class_getitem__(cls, ch):
|
||||
if (rpl := cls.hardcoded.get(ch)) is not None:
|
||||
return rpl
|
||||
if ch in range(0x20, 0x7f):
|
||||
if ch in range(0x20, 0x7F):
|
||||
return ch
|
||||
return f"\\u{{{ch:x}}}"
|
||||
|
||||
|
||||
def rust_str(s):
|
||||
return '"' + s.translate(EscapeRustStr) + '"'
|
||||
|
||||
|
||||
# matches `// pattern {varname} = re.compile(...)`
|
||||
pattern_pattern = re.compile(r"^((\s*)\/\/\s*pattern\s+(\w+)\s+=\s+(.+?))$(?:.+?END GENERATED)?", re.M | re.S)
|
||||
pattern_pattern = re.compile(
|
||||
r"^((\s*)\/\/\s*pattern\s+(\w+)\s+=\s+(.+?))$(?:.+?END GENERATED)?", re.M | re.S
|
||||
)
|
||||
|
||||
|
||||
def replace_compiled(m):
|
||||
line, indent, varname, pattern = m.groups()
|
||||
pattern = eval(pattern, {"re": CompiledPattern})
|
||||
pattern = f"Pattern {{ pattern: {rust_str(pattern.pattern)}, code: &{json.dumps(pattern.code)} }}"
|
||||
return f'''{line}
|
||||
return f"""{line}
|
||||
{indent}// START GENERATED by generate_tests.py
|
||||
{indent}#[rustfmt::skip] let {varname} = {pattern};
|
||||
{indent}// END GENERATED'''
|
||||
{indent}// END GENERATED"""
|
||||
|
||||
|
||||
with os.scandir("tests") as t, os.scandir("benches") as b:
|
||||
for f in chain(t, b):
|
||||
|
||||
22
wasm/demo/package-lock.json
generated
22
wasm/demo/package-lock.json
generated
@@ -24,7 +24,7 @@
|
||||
"serve": "^14.2.4",
|
||||
"webpack": "^5.97.1",
|
||||
"webpack-cli": "^6.0.1",
|
||||
"webpack-dev-server": "^5.2.0"
|
||||
"webpack-dev-server": "^5.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
@@ -5360,15 +5360,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-server": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.0.tgz",
|
||||
"integrity": "sha512-90SqqYXA2SK36KcT6o1bvwvZfJFcmoamqeJY7+boioffX9g9C0wjjJRGUrQIuh43pb0ttX7+ssavmj/WN2RHtA==",
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.1.tgz",
|
||||
"integrity": "sha512-ml/0HIj9NLpVKOMq+SuBPLHcmbG+TGIjXRHsYfZwocUBIqEvws8NnS/V9AFQ5FKP+tgn5adwVwRrTEpGL33QFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/bonjour": "^3.5.13",
|
||||
"@types/connect-history-api-fallback": "^1.5.4",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/express-serve-static-core": "^4.17.21",
|
||||
"@types/serve-index": "^1.9.4",
|
||||
"@types/serve-static": "^1.15.5",
|
||||
"@types/sockjs": "^0.3.36",
|
||||
@@ -5416,6 +5417,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-server/node_modules/@types/express-serve-static-core": {
|
||||
"version": "4.19.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
|
||||
"integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/range-parser": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-merge": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"serve": "^14.2.4",
|
||||
"webpack": "^5.97.1",
|
||||
"webpack-cli": "^6.0.1",
|
||||
"webpack-dev-server": "^5.2.0"
|
||||
"webpack-dev-server": "^5.2.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "webpack serve",
|
||||
|
||||
@@ -28,9 +28,6 @@ ruff_python_parser = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
wasm-bindgen = { workspace = true }
|
||||
|
||||
# remove once getrandom 0.2 is no longer otherwise in the dependency tree
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
|
||||
console_error_panic_hook = "0.1"
|
||||
js-sys = "0.3"
|
||||
serde-wasm-bindgen = "0.3.1"
|
||||
|
||||
@@ -7,8 +7,7 @@ edition = "2021"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
getrandom = { version = "0.2.12", features = ["custom"] }
|
||||
getrandom_03 = { package = "getrandom", version = "0.3" }
|
||||
getrandom = "0.3"
|
||||
rustpython-vm = { path = "../../vm", default-features = false, features = ["compiler"] }
|
||||
|
||||
[workspace]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use rustpython_vm::{eval, Interpreter};
|
||||
use rustpython_vm::{Interpreter, eval};
|
||||
|
||||
pub unsafe extern "C" fn eval(s: *const u8, l: usize) -> u32 {
|
||||
let src = std::slice::from_raw_parts(s, l);
|
||||
@@ -9,16 +9,10 @@ pub unsafe extern "C" fn eval(s: *const u8, l: usize) -> u32 {
|
||||
})
|
||||
}
|
||||
|
||||
fn getrandom_always_fail(_buf: &mut [u8]) -> Result<(), getrandom::Error> {
|
||||
Err(getrandom::Error::UNSUPPORTED)
|
||||
}
|
||||
|
||||
getrandom::register_custom_getrandom!(getrandom_always_fail);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "Rust" fn __getrandom_v03_custom(
|
||||
_dest: *mut u8,
|
||||
_len: usize,
|
||||
) -> Result<(), getrandom_03::Error> {
|
||||
Err(getrandom_03::Error::UNSUPPORTED)
|
||||
) -> Result<(), getrandom::Error> {
|
||||
Err(getrandom::Error::UNSUPPORTED)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,10 @@ implementation = platform.python_implementation()
|
||||
if implementation != "CPython":
|
||||
sys.exit(f"whats_left.py must be run under CPython, got {implementation} instead")
|
||||
if sys.version_info[:2] < (3, 13):
|
||||
sys.exit(f"whats_left.py must be run under CPython 3.13 or newer, got {implementation} {sys.version} instead")
|
||||
sys.exit(
|
||||
f"whats_left.py must be run under CPython 3.13 or newer, got {implementation} {sys.version} instead. If you have uv, try `uv run python -I whats_left.py` to select a proper Python interpreter easier."
|
||||
)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Process some integers.")
|
||||
@@ -73,8 +76,16 @@ args = parse_args()
|
||||
|
||||
# CPython specific modules (mostly consisting of templates/tests)
|
||||
CPYTHON_SPECIFIC_MODS = {
|
||||
'xxmodule', 'xxsubtype', 'xxlimited', '_xxtestfuzz',
|
||||
'_testbuffer', '_testcapi', '_testimportmultiple', '_testinternalcapi', '_testmultiphase', '_testlimitedcapi'
|
||||
"xxmodule",
|
||||
"xxsubtype",
|
||||
"xxlimited",
|
||||
"_xxtestfuzz",
|
||||
"_testbuffer",
|
||||
"_testcapi",
|
||||
"_testimportmultiple",
|
||||
"_testinternalcapi",
|
||||
"_testmultiphase",
|
||||
"_testlimitedcapi",
|
||||
}
|
||||
|
||||
IGNORED_MODULES = {"this", "antigravity"} | CPYTHON_SPECIFIC_MODS
|
||||
@@ -291,7 +302,7 @@ output = """\
|
||||
output += gen_methods()
|
||||
output += f"""
|
||||
cpymods = {gen_modules()!r}
|
||||
libdir = {os.path.abspath("Lib/").encode('utf8')!r}
|
||||
libdir = {os.path.abspath("Lib/").encode("utf8")!r}
|
||||
|
||||
"""
|
||||
|
||||
@@ -310,6 +321,8 @@ for fn in REUSED:
|
||||
expected_methods = {}
|
||||
cpymods = {}
|
||||
libdir = ""
|
||||
|
||||
|
||||
# This function holds the source code that will be run under RustPython
|
||||
def compare():
|
||||
import inspect
|
||||
@@ -376,7 +389,9 @@ def compare():
|
||||
if rustpymod is None:
|
||||
result["not_implemented"][modname] = None
|
||||
elif isinstance(rustpymod, Exception):
|
||||
result["failed_to_import"][modname] = rustpymod.__class__.__name__ + str(rustpymod)
|
||||
result["failed_to_import"][modname] = rustpymod.__class__.__name__ + str(
|
||||
rustpymod
|
||||
)
|
||||
else:
|
||||
implemented_items = sorted(set(cpymod) & set(rustpymod))
|
||||
mod_missing_items = set(cpymod) - set(rustpymod)
|
||||
@@ -418,13 +433,23 @@ def remove_one_indent(s):
|
||||
compare_src = inspect.getsourcelines(compare)[0][1:]
|
||||
output += "".join(remove_one_indent(line) for line in compare_src)
|
||||
|
||||
with open(GENERATED_FILE, "w", encoding='utf-8') as f:
|
||||
with open(GENERATED_FILE, "w", encoding="utf-8") as f:
|
||||
f.write(output + "\n")
|
||||
|
||||
|
||||
subprocess.run(["cargo", "build", "--release", f"--features={args.features}"], check=True)
|
||||
subprocess.run(
|
||||
["cargo", "build", "--release", f"--features={args.features}"], check=True
|
||||
)
|
||||
result = subprocess.run(
|
||||
["cargo", "run", "--release", f"--features={args.features}", "-q", "--", GENERATED_FILE],
|
||||
[
|
||||
"cargo",
|
||||
"run",
|
||||
"--release",
|
||||
f"--features={args.features}",
|
||||
"-q",
|
||||
"--",
|
||||
GENERATED_FILE,
|
||||
],
|
||||
env={**os.environ.copy(), "RUSTPYTHONPATH": "Lib"},
|
||||
text=True,
|
||||
capture_output=True,
|
||||
@@ -475,7 +500,7 @@ if args.signature:
|
||||
if args.doc:
|
||||
print("\n# mismatching `__doc__`s (warnings)")
|
||||
for modname, mismatched in result["mismatched_doc_items"].items():
|
||||
for (item, rustpy_doc, cpython_doc) in mismatched:
|
||||
for item, rustpy_doc, cpython_doc in mismatched:
|
||||
print(f"{item} {repr(rustpy_doc)} != {repr(cpython_doc)}")
|
||||
|
||||
|
||||
|
||||
@@ -676,7 +676,7 @@ impl fmt::Debug for Wtf8 {
|
||||
write_str_escaped(formatter, unsafe {
|
||||
str::from_utf8_unchecked(&self.bytes[pos..surrogate_pos])
|
||||
})?;
|
||||
write!(formatter, "\\u{{{:x}}}", surrogate)?;
|
||||
write!(formatter, "\\u{{{surrogate:x}}}")?;
|
||||
pos = surrogate_pos + 3;
|
||||
}
|
||||
write_str_escaped(formatter, unsafe {
|
||||
|
||||
Reference in New Issue
Block a user