From b6095df543fa38f2ab2986d2acb2ecb12c4b9b50 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 13 Jun 2023 21:31:25 +0900 Subject: [PATCH] !!don't merge!! revert to prev #4978 --- .github/workflows/ci.yaml | 34 +-- .github/workflows/cron-ci.yaml | 48 ++-- Cargo.lock | 345 +++++++-------------------- Cargo.toml | 15 +- Lib/aifc.py | 65 ++--- Lib/cgi.py | 46 +--- Lib/cgitb.py | 23 +- Lib/chunk.py | 6 +- Lib/cmd.py | 10 +- Lib/codeop.py | 95 +++++--- Lib/colorsys.py | 28 +-- Lib/test/test_cgi.py | 19 +- Lib/test/test_cgitb.py | 15 +- Lib/test/test_cmd.py | 45 +--- Lib/test/test_compile.py | 2 + Lib/test/test_itertools.py | 2 + Lib/test/test_opcode.py | 356 ---------------------------- Lib/test/test_plistlib.py | 2 + Lib/test/test_runpy.py | 2 + Lib/warnings.py | 104 +++----- README.md | 2 - architecture/architecture.md | 150 ------------ architecture/overview.png | Bin 35246 -> 0 bytes benches/microbenchmarks.rs | 22 -- common/Cargo.toml | 5 +- common/src/float_ops.rs | 4 +- common/src/hash.rs | 2 +- common/src/int.rs | 32 +-- compiler/codegen/src/compile.rs | 32 ++- compiler/codegen/src/symboltable.rs | 60 +++-- compiler/core/Cargo.toml | 2 +- compiler/core/src/bytecode.rs | 2 +- compiler/core/src/marshal.rs | 2 +- compiler/src/lib.rs | 14 +- extra_tests/snippets/stdlib_os.py | 1 - scripts/cargo-llvm-cov.py | 20 -- stdlib/Cargo.toml | 7 +- stdlib/src/json.rs | 2 +- stdlib/src/math.rs | 11 +- stdlib/src/random.rs | 4 +- stdlib/src/resource.rs | 6 +- stdlib/src/sqlite.rs | 7 +- vm/Cargo.toml | 3 +- vm/src/buffer.rs | 2 +- vm/src/builtins/bool.rs | 2 +- vm/src/builtins/code.rs | 3 +- vm/src/builtins/enumerate.rs | 2 +- vm/src/builtins/float.rs | 28 ++- vm/src/builtins/int.rs | 13 +- vm/src/builtins/range.rs | 2 +- vm/src/builtins/slice.rs | 2 +- vm/src/bytesinner.rs | 2 +- vm/src/dictdatatype.rs | 2 +- vm/src/function/number.rs | 2 +- vm/src/macros.rs | 4 +- vm/src/sliceable.rs | 2 +- vm/src/stdlib/ast.rs | 18 +- vm/src/stdlib/ast/gen.rs | 264 ++++++++++++++++++++- vm/src/stdlib/builtins.rs | 5 +- vm/src/stdlib/io.rs | 7 +- vm/src/stdlib/itertools.rs | 49 +--- vm/src/stdlib/marshal.rs | 2 +- vm/src/stdlib/os.rs | 1 - vm/src/stdlib/thread.rs | 6 +- vm/src/vm/context.rs | 2 +- vm/src/vm/interpreter.rs | 2 +- vm/src/vm/setting.rs | 8 - 67 files changed, 713 insertions(+), 1369 deletions(-) delete mode 100644 Lib/test/test_opcode.py delete mode 100644 architecture/architecture.md delete mode 100644 architecture/overview.png delete mode 100644 scripts/cargo-llvm-cov.py diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 15d97ae1b2..cfbf439892 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,23 +16,6 @@ concurrency: env: CARGO_ARGS: --no-default-features --features stdlib,zlib,importlib,encodings,ssl,jit - # Skip additional tests on Windows. They are checked on Linux and MacOS. - WINDOWS_SKIPS: >- - test_glob - test_importlib - test_io - test_os - test_pathlib - test_posixpath - test_shutil - 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: >- test_argparse test_array @@ -269,16 +252,21 @@ jobs: name: run cpython platform-independent tests run: target/release/rustpython -m test -j 1 -u all --slowest --fail-env-changed -v ${{ env.PLATFORM_INDEPENDENT_TESTS }} - - if: runner.os == 'Linux' - name: run cpython platform-dependent tests (Linux) + - if: runner.os != 'Windows' + name: run cpython platform-dependent tests 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 -u all --slowest --fail-env-changed -v -x ${{ env.PLATFORM_INDEPENDENT_TESTS }} ${{ env.MACOS_SKIPS }} - if: runner.os == 'Windows' name: run cpython platform-dependent tests (windows partial - fixme) run: - target/release/rustpython -m test -j 1 -u all --slowest --fail-env-changed -v -x ${{ env.PLATFORM_INDEPENDENT_TESTS }} ${{ env.WINDOWS_SKIPS }} + target/release/rustpython -m test -j 1 -u all --slowest --fail-env-changed -v -x ${{ env.PLATFORM_INDEPENDENT_TESTS }} + test_glob + test_importlib + test_io + test_os + test_pathlib + test_posixpath + test_shutil + test_venv - if: runner.os != 'Windows' name: check that --install-pip succeeds run: | diff --git a/.github/workflows/cron-ci.yaml b/.github/workflows/cron-ci.yaml index 86ce3d7263..8ef531074c 100644 --- a/.github/workflows/cron-ci.yaml +++ b/.github/workflows/cron-ci.yaml @@ -6,33 +6,50 @@ on: name: Periodic checks/tasks env: - CARGO_ARGS: --no-default-features --features stdlib,zlib,importlib,encodings,ssl,jit + CARGO_ARGS: --features ssl,jit jobs: - # codecov collects code coverage data from the rust tests, python snippets and python test suite. - # This is done using cargo-llvm-cov, which is a wrapper around llvm-cov. codecov: name: Collect code coverage data runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable - - uses: taiki-e/install-action@cargo-llvm-cov + with: + components: llvm-tools-preview + - run: sudo apt-get update && sudo apt-get -y install lcov + - run: cargo build --release --verbose ${{ env.CARGO_ARGS }} + env: + RUSTC_WRAPPER: './scripts/codecoverage-rustc-wrapper.sh' - uses: actions/setup-python@v4 with: python-version: "3.11" - - run: sudo apt-get update && sudo apt-get -y install lcov - - name: Run cargo-llvm-cov with Rust tests. - run: cargo llvm-cov --no-report --workspace --exclude rustpython_wasm --verbose --no-default-features --features stdlib,zlib,importlib,encodings,ssl,jit - - name: Run cargo-llvm-cov with Python snippets. - run: python scripts/cargo-llvm-cov.py + - run: python -m pip install pytest + working-directory: ./extra_tests + - name: run snippets + run: LLVM_PROFILE_FILE="$PWD/snippet-%p.profraw" pytest -v + working-directory: ./extra_tests continue-on-error: true - - name: Run cargo-llvm-cov with Python test suite. - run: cargo llvm-cov --no-report run -- -m test -u all --slowest --fail-env-changed + - name: run cpython tests + run: | + alltests=($(target/release/rustpython -c 'from test.libregrtest.runtest import findtests; print(*findtests())')) + i=0 + # chunk into chunks of 10 tests each. idk at this point + while subtests=("${alltests[@]:$i:10}"); [[ ${#subtests[@]} -ne 0 ]]; do + LLVM_PROFILE_FILE="$PWD/regrtest-%p.profraw" target/release/rustpython -m test -v "${subtests[@]}" || true + ((i+=10)) + done continue-on-error: true - - name: Prepare code coverage data - run: cargo llvm-cov report --lcov --output-path='codecov.lcov' - - name: Upload to Codecov + - name: prepare code coverage data + run: | + rusttool() { + local tool=$1; shift; "$(rustc --print target-libdir)/../bin/llvm-$tool" "$@" + } + rusttool profdata merge extra_tests/snippet-*.profraw regrtest-*.profraw --output codecov.profdata + rusttool cov export --instr-profile codecov.profdata target/release/rustpython --format lcov > codecov_tmp.lcov + lcov -e codecov_tmp.lcov "$PWD"/'*' -o codecov_tmp2.lcov + lcov -r codecov_tmp2.lcov "$PWD"/target/'*' -o codecov.lcov # remove LALRPOP-generated parser + - name: upload to Codecov uses: codecov/codecov-action@v3 with: file: ./codecov.lcov @@ -72,9 +89,6 @@ jobs: steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable - - uses: actions/setup-python@v4 - with: - python-version: "3.11" - name: build rustpython run: cargo build --release --verbose - name: Collect what is left data diff --git a/Cargo.lock b/Cargo.lock index 298e14f3f4..c1365ecdd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.8", + "getrandom", "once_cell", "version_check", ] @@ -125,9 +125,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813" [[package]] name = "blake2" @@ -135,17 +135,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding", - "generic-array", + "digest", ] [[package]] @@ -157,12 +147,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bstr" version = "0.2.17" @@ -308,12 +292,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "core-foundation" version = "0.9.3" @@ -487,7 +465,7 @@ dependencies = [ "clap", "criterion-plot", "csv", - "itertools 0.10.5", + "itertools", "lazy_static 1.4.0", "num-traits", "oorandom", @@ -509,7 +487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ "cast", - "itertools 0.10.5", + "itertools", ] [[package]] @@ -636,35 +614,13 @@ dependencies = [ "syn", ] -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.3", + "block-buffer", "crypto-common", "subtle", ] @@ -714,18 +670,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" -[[package]] -name = "embed-doc-image" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af36f591236d9d822425cb6896595658fa558fcebf5ee8accac1d4b92c47166e" -dependencies = [ - "base64", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "encode_unicode" version = "0.3.6" @@ -894,17 +838,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.8" @@ -1049,15 +982,6 @@ dependencies = [ "syn", ] -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1255,65 +1179,6 @@ dependencies = [ "libc", ] -[[package]] -name = "malachite" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6cf7f4730c30071ba374fac86ad35b1cb7a0716f774737768667ea3fa1828e3" -dependencies = [ - "malachite-base", - "malachite-nz", - "malachite-q", -] - -[[package]] -name = "malachite-base" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b06bfa98a4b4802af5a4263b4ad4660e28e51e8490f6354eb9336c70767e1c5" -dependencies = [ - "itertools 0.9.0", - "rand 0.7.3", - "rand_chacha 0.2.2", - "ryu", - "sha3 0.9.1", -] - -[[package]] -name = "malachite-bigint" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a5110aee54537b0cef214efbebdd7df79b7408db8eef4f6a4b6db9d0d8fc01b" -dependencies = [ - "derive_more", - "malachite", - "num-integer", - "num-traits", - "paste", -] - -[[package]] -name = "malachite-nz" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89e21c64b7af5be3dc8cef16f786243faf59459fe4ba93b44efdeb264e5ade4" -dependencies = [ - "embed-doc-image", - "itertools 0.9.0", - "malachite-base", -] - -[[package]] -name = "malachite-q" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3755e541d5134b5016594c9043094172c4dda9259b3ce824a7b8101941850360" -dependencies = [ - "itertools 0.9.0", - "malachite-base", - "malachite-nz", -] - [[package]] name = "maplit" version = "1.0.2" @@ -1332,7 +1197,7 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ - "digest 0.10.6", + "digest", ] [[package]] @@ -1383,7 +1248,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12ca7f22ed370d5991a9caec16a83187e865bc8a532f889670337d5a5689e3a1" dependencies = [ - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -1431,6 +1296,17 @@ dependencies = [ "memchr", ] +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-complex" version = "0.4.3" @@ -1450,6 +1326,18 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -1502,12 +1390,6 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "openssl" version = "0.10.48" @@ -1604,9 +1486,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.12" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" [[package]] name = "phf" @@ -1634,7 +1516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" dependencies = [ "phf_shared", - "rand 0.8.5", + "rand", ] [[package]] @@ -1763,19 +1645,6 @@ dependencies = [ "nibble_vec", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -1783,18 +1652,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -1804,16 +1663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -1822,16 +1672,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.8", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] @@ -1877,7 +1718,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.8", + "getrandom", "redox_syscall 0.2.16", "thiserror", ] @@ -1954,7 +1795,7 @@ dependencies = [ [[package]] name = "ruff_source_location" version = "0.0.0" -source = "git+https://github.com/RustPython/Parser.git?rev=b2f95e284852cb25d6e510c127260d03573d9f0c#b2f95e284852cb25d6e510c127260d03573d9f0c" +source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec#fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" dependencies = [ "memchr", "once_cell", @@ -1964,7 +1805,7 @@ dependencies = [ [[package]] name = "ruff_text_size" version = "0.0.0" -source = "git+https://github.com/RustPython/Parser.git?rev=b2f95e284852cb25d6e510c127260d03573d9f0c#b2f95e284852cb25d6e510c127260d03573d9f0c" +source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec#fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" [[package]] name = "rustc-hash" @@ -2022,10 +1863,10 @@ dependencies = [ [[package]] name = "rustpython-ast" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=b2f95e284852cb25d6e510c127260d03573d9f0c#b2f95e284852cb25d6e510c127260d03573d9f0c" +source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec#fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" dependencies = [ "is-macro", - "malachite-bigint", + "num-bigint", "rustpython-literal", "rustpython-parser-core", "static_assertions", @@ -2036,10 +1877,10 @@ name = "rustpython-codegen" version = "0.2.0" dependencies = [ "ahash", - "bitflags 2.3.1", + "bitflags 2.2.1", "indexmap", "insta", - "itertools 0.10.5", + "itertools", "log", "num-complex", "num-traits", @@ -2054,21 +1895,18 @@ name = "rustpython-common" version = "0.2.0" dependencies = [ "ascii", - "bitflags 2.3.1", + "bitflags 2.2.1", "bstr", "cfg-if", - "itertools 0.10.5", + "itertools", "libc", "lock_api", - "malachite-base", - "malachite-bigint", - "malachite-q", - "num-complex", + "num-bigint", "num-traits", "once_cell", "parking_lot", "radium", - "rand 0.8.5", + "rand", "rustpython-format", "siphasher", "volatile", @@ -2088,10 +1926,10 @@ dependencies = [ name = "rustpython-compiler-core" version = "0.2.0" dependencies = [ - "bitflags 2.3.1", - "itertools 0.10.5", + "bitflags 2.2.1", + "itertools", "lz4_flex", - "malachite-bigint", + "num-bigint", "num-complex", "rustpython-parser-core", "serde", @@ -2110,7 +1948,7 @@ dependencies = [ name = "rustpython-derive-impl" version = "0.2.0" dependencies = [ - "itertools 0.10.5", + "itertools", "maplit", "once_cell", "proc-macro2", @@ -2134,11 +1972,11 @@ dependencies = [ [[package]] name = "rustpython-format" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=b2f95e284852cb25d6e510c127260d03573d9f0c#b2f95e284852cb25d6e510c127260d03573d9f0c" +source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec#fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" dependencies = [ - "bitflags 2.3.1", - "itertools 0.10.5", - "malachite-bigint", + "bitflags 2.2.1", + "itertools", + "num-bigint", "num-traits", "rustpython-literal", ] @@ -2161,7 +1999,7 @@ dependencies = [ [[package]] name = "rustpython-literal" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=b2f95e284852cb25d6e510c127260d03573d9f0c#b2f95e284852cb25d6e510c127260d03573d9f0c" +source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec#fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" dependencies = [ "hexf-parse", "is-macro", @@ -2173,14 +2011,14 @@ dependencies = [ [[package]] name = "rustpython-parser" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=b2f95e284852cb25d6e510c127260d03573d9f0c#b2f95e284852cb25d6e510c127260d03573d9f0c" +source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec#fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" dependencies = [ "anyhow", "is-macro", - "itertools 0.10.5", + "itertools", "lalrpop-util", "log", - "malachite-bigint", + "num-bigint", "num-traits", "phf", "phf_codegen", @@ -2196,10 +2034,9 @@ dependencies = [ [[package]] name = "rustpython-parser-core" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=b2f95e284852cb25d6e510c127260d03573d9f0c#b2f95e284852cb25d6e510c127260d03573d9f0c" +source = "git+https://github.com/youknowone/RustPython-Parser.git?rev=fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec#fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" dependencies = [ "is-macro", - "memchr", "ruff_source_location", "ruff_text_size", ] @@ -2227,26 +2064,27 @@ dependencies = [ "crc32fast", "crossbeam-utils", "csv-core", - "digest 0.10.6", + "digest", "dns-lookup", "dyn-clone", "flate2", "foreign-types-shared", "gethostname", "hex", - "itertools 0.10.5", + "itertools", "libc", "libsqlite3-sys", "libz-sys", "mac_address", - "malachite-bigint", "md-5", "memchr", "memmap2", "mt19937", "nix 0.26.2", + "num-bigint", "num-complex", "num-integer", + "num-rational", "num-traits", "num_enum", "once_cell", @@ -2257,15 +2095,15 @@ dependencies = [ "parking_lot", "paste", "puruspe", - "rand 0.8.5", - "rand_core 0.6.4", + "rand", + "rand_core", "rustpython-common", "rustpython-derive", "rustpython-vm", "schannel", "sha-1", "sha2", - "sha3 0.10.6", + "sha3", "socket2", "system-configuration", "termios", @@ -2291,7 +2129,7 @@ dependencies = [ "ahash", "ascii", "atty", - "bitflags 2.3.1", + "bitflags 2.2.1", "bstr", "caseless", "cfg-if", @@ -2300,21 +2138,22 @@ dependencies = [ "exitcode", "flame", "flamer", - "getrandom 0.2.8", + "getrandom", "glob", "half", "hex", "indexmap", "is-macro", - "itertools 0.10.5", + "itertools", "libc", "log", - "malachite-bigint", "memchr", "memoffset 0.6.5", "nix 0.26.2", + "num-bigint", "num-complex", "num-integer", + "num-rational", "num-traits", "num_cpus", "num_enum", @@ -2322,7 +2161,7 @@ dependencies = [ "optional", "parking_lot", "paste", - "rand 0.8.5", + "rand", "result-like", "rustc_version", "rustpython-ast", @@ -2510,7 +2349,7 @@ checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest", ] [[package]] @@ -2521,19 +2360,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", + "digest", ] [[package]] @@ -2542,7 +2369,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" dependencies = [ - "digest 0.10.6", + "digest", "keccak", ] @@ -3024,8 +2851,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ "atomic", - "getrandom 0.2.8", - "rand 0.8.5", + "getrandom", + "rand", "uuid-macro-internal", ] @@ -3075,12 +2902,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -3461,9 +3282,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.14" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52839dc911083a8ef63efa4d039d1f58b5e409f923e44c80828f206f66e5541c" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" [[package]] name = "yaml-rust" diff --git a/Cargo.toml b/Cargo.toml index 4dd4b25662..39f1103d5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,11 +29,11 @@ rustpython-pylib = { path = "pylib" } rustpython-stdlib = { path = "stdlib" } rustpython-doc = { git = "https://github.com/RustPython/__doc__", branch = "main" } -rustpython-literal = { git = "https://github.com/RustPython/Parser.git", rev = "b2f95e284852cb25d6e510c127260d03573d9f0c" } -rustpython-parser-core = { git = "https://github.com/RustPython/Parser.git", rev = "b2f95e284852cb25d6e510c127260d03573d9f0c" } -rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "b2f95e284852cb25d6e510c127260d03573d9f0c" } -rustpython-ast = { git = "https://github.com/RustPython/Parser.git", rev = "b2f95e284852cb25d6e510c127260d03573d9f0c" } -rustpython-format = { git = "https://github.com/RustPython/Parser.git", rev = "b2f95e284852cb25d6e510c127260d03573d9f0c" } +rustpython-literal = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" } +rustpython-parser-core = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" } +rustpython-parser = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" } +rustpython-ast = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" } +rustpython-format = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" } # rustpython-literal = { path = "../RustPython-parser/literal" } # rustpython-parser-core = { path = "../RustPython-parser/core" } # rustpython-parser = { path = "../RustPython-parser/parser" } @@ -58,11 +58,10 @@ itertools = "0.10.3" libc = "0.2.133" log = "0.4.16" nix = "0.26" -malachite-bigint = { version = "0.1.0" } -malachite-q = "0.3.2" -malachite-base = "0.3.2" num-complex = "0.4.0" +num-bigint = "0.4.3" num-integer = "0.1.44" +num-rational = "0.4.0" num-traits = "0.2" num_enum = "0.5.7" once_cell = "1.13" diff --git a/Lib/aifc.py b/Lib/aifc.py index 5254987e22..1916e7ef8e 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -138,11 +138,7 @@ import builtins import warnings -__all__ = ["Error", "open"] - - -warnings._deprecated(__name__, remove=(3, 13)) - +__all__ = ["Error", "open", "openfp"] class Error(Exception): pass @@ -255,9 +251,7 @@ def _write_float(f, x): _write_ulong(f, himant) _write_ulong(f, lomant) -with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - from chunk import Chunk +from chunk import Chunk from collections import namedtuple _aifc_params = namedtuple('_aifc_params', @@ -453,33 +447,21 @@ def readframes(self, nframes): # def _alaw2lin(self, data): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - import audioop + import audioop return audioop.alaw2lin(data, 2) def _ulaw2lin(self, data): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - import audioop + import audioop return audioop.ulaw2lin(data, 2) def _adpcm2lin(self, data): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - import audioop + import audioop if not hasattr(self, '_adpcmstate'): # first time self._adpcmstate = None data, self._adpcmstate = audioop.adpcm2lin(data, 2, self._adpcmstate) return data - def _sowt2lin(self, data): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - import audioop - return audioop.byteswap(data, 2) - def _read_comm_chunk(self, chunk): self._nchannels = _read_short(chunk) self._nframes = _read_long(chunk) @@ -515,8 +497,6 @@ def _read_comm_chunk(self, chunk): self._convert = self._ulaw2lin elif self._comptype in (b'alaw', b'ALAW'): self._convert = self._alaw2lin - elif self._comptype in (b'sowt', b'SOWT'): - self._convert = self._sowt2lin else: raise Error('unsupported compression type') self._sampwidth = 2 @@ -679,7 +659,7 @@ def setcomptype(self, comptype, compname): if self._nframeswritten: raise Error('cannot change parameters after starting to write') if comptype not in (b'NONE', b'ulaw', b'ULAW', - b'alaw', b'ALAW', b'G722', b'sowt', b'SOWT'): + b'alaw', b'ALAW', b'G722'): raise Error('unsupported compression type') self._comptype = comptype self._compname = compname @@ -700,7 +680,7 @@ def setparams(self, params): if self._nframeswritten: raise Error('cannot change parameters after starting to write') if comptype not in (b'NONE', b'ulaw', b'ULAW', - b'alaw', b'ALAW', b'G722', b'sowt', b'SOWT'): + b'alaw', b'ALAW', b'G722'): raise Error('unsupported compression type') self.setnchannels(nchannels) self.setsampwidth(sampwidth) @@ -784,43 +764,28 @@ def close(self): # def _lin2alaw(self, data): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - import audioop + import audioop return audioop.lin2alaw(data, 2) def _lin2ulaw(self, data): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - import audioop + import audioop return audioop.lin2ulaw(data, 2) def _lin2adpcm(self, data): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - import audioop + import audioop if not hasattr(self, '_adpcmstate'): self._adpcmstate = None data, self._adpcmstate = audioop.lin2adpcm(data, 2, self._adpcmstate) return data - def _lin2sowt(self, data): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - import audioop - return audioop.byteswap(data, 2) - def _ensure_header_written(self, datasize): if not self._nframeswritten: - if self._comptype in (b'ULAW', b'ulaw', - b'ALAW', b'alaw', b'G722', - b'sowt', b'SOWT'): + if self._comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'): if not self._sampwidth: self._sampwidth = 2 if self._sampwidth != 2: raise Error('sample width must be 2 when compressing ' - 'with ulaw/ULAW, alaw/ALAW, sowt/SOWT ' - 'or G7.22 (ADPCM)') + 'with ulaw/ULAW, alaw/ALAW or G7.22 (ADPCM)') if not self._nchannels: raise Error('# channels not specified') if not self._sampwidth: @@ -836,8 +801,6 @@ def _init_compression(self): self._convert = self._lin2ulaw elif self._comptype in (b'alaw', b'ALAW'): self._convert = self._lin2alaw - elif self._comptype in (b'sowt', b'SOWT'): - self._convert = self._lin2sowt def _write_header(self, initlength): if self._aifc and self._comptype != b'NONE': @@ -957,6 +920,10 @@ def open(f, mode=None): else: raise Error("mode must be 'r', 'rb', 'w', or 'wb'") +def openfp(f, mode=None): + warnings.warn("aifc.openfp is deprecated since Python 3.7. " + "Use aifc.open instead.", DeprecationWarning, stacklevel=2) + return open(f, mode=mode) if __name__ == '__main__': import sys diff --git a/Lib/cgi.py b/Lib/cgi.py index 8787567be7..c22c71b387 100755 --- a/Lib/cgi.py +++ b/Lib/cgi.py @@ -13,11 +13,6 @@ This module defines a number of utilities for use by CGI scripts written in Python. - -The global variable maxlen can be set to an integer indicating the maximum size -of a POST request. POST requests larger than this size will result in a -ValueError being raised during parsing. The default value of this variable is 0, -meaning the request size is unlimited. """ # History @@ -46,16 +41,12 @@ import html import locale import tempfile -import warnings __all__ = ["MiniFieldStorage", "FieldStorage", "parse", "parse_multipart", "parse_header", "test", "print_exception", "print_environ", "print_form", "print_directory", "print_arguments", "print_environ_usage"] - -warnings._deprecated(__name__, remove=(3,13)) - # Logging support # =============== @@ -86,11 +77,9 @@ def initlog(*allargs): """ global log, logfile, logfp - warnings.warn("cgi.log() is deprecated as of 3.10. Use logging instead", - DeprecationWarning, stacklevel=2) if logfile and not logfp: try: - logfp = open(logfile, "a", encoding="locale") + logfp = open(logfile, "a") except OSError: pass if not logfp: @@ -126,8 +115,7 @@ def closelog(): # 0 ==> unlimited input maxlen = 0 -def parse(fp=None, environ=os.environ, keep_blank_values=0, - strict_parsing=0, separator='&'): +def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0): """Parse a query in the environment or from a file (default stdin) Arguments, all optional: @@ -146,9 +134,6 @@ def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing: flag indicating what to do with parsing errors. If false (the default), errors are silently ignored. If true, errors raise a ValueError exception. - - separator: str. The symbol to use for separating the query arguments. - Defaults to &. """ if fp is None: fp = sys.stdin @@ -169,7 +154,7 @@ def parse(fp=None, environ=os.environ, keep_blank_values=0, if environ['REQUEST_METHOD'] == 'POST': ctype, pdict = parse_header(environ['CONTENT_TYPE']) if ctype == 'multipart/form-data': - return parse_multipart(fp, pdict, separator=separator) + return parse_multipart(fp, pdict) elif ctype == 'application/x-www-form-urlencoded': clength = int(environ['CONTENT_LENGTH']) if maxlen and clength > maxlen: @@ -193,10 +178,10 @@ def parse(fp=None, environ=os.environ, keep_blank_values=0, qs = "" environ['QUERY_STRING'] = qs # XXX Shouldn't, really return urllib.parse.parse_qs(qs, keep_blank_values, strict_parsing, - encoding=encoding, separator=separator) + encoding=encoding) -def parse_multipart(fp, pdict, encoding="utf-8", errors="replace", separator='&'): +def parse_multipart(fp, pdict, encoding="utf-8", errors="replace"): """Parse multipart input. Arguments: @@ -209,18 +194,15 @@ def parse_multipart(fp, pdict, encoding="utf-8", errors="replace", separator='&' value is a list of values for that field. For non-file fields, the value is a list of strings. """ - # RFC 2046, Section 5.1 : The "multipart" boundary delimiters are always + # RFC 2026, Section 5.1 : The "multipart" boundary delimiters are always # represented as 7bit US-ASCII. boundary = pdict['boundary'].decode('ascii') ctype = "multipart/form-data; boundary={}".format(boundary) headers = Message() headers.set_type(ctype) - try: - headers['Content-Length'] = pdict['CONTENT-LENGTH'] - except KeyError: - pass + headers['Content-Length'] = pdict['CONTENT-LENGTH'] fs = FieldStorage(fp, headers=headers, encoding=encoding, errors=errors, - environ={'REQUEST_METHOD': 'POST'}, separator=separator) + environ={'REQUEST_METHOD': 'POST'}) return {k: fs.getlist(k) for k in fs} def _parseparam(s): @@ -330,7 +312,7 @@ class FieldStorage: def __init__(self, fp=None, headers=None, outerboundary=b'', environ=os.environ, keep_blank_values=0, strict_parsing=0, limit=None, encoding='utf-8', errors='replace', - max_num_fields=None, separator='&'): + max_num_fields=None): """Constructor. Read multipart/* until last part. Arguments, all optional: @@ -378,7 +360,6 @@ def __init__(self, fp=None, headers=None, outerboundary=b'', self.keep_blank_values = keep_blank_values self.strict_parsing = strict_parsing self.max_num_fields = max_num_fields - self.separator = separator if 'REQUEST_METHOD' in environ: method = environ['REQUEST_METHOD'].upper() self.qs_on_post = None @@ -605,7 +586,7 @@ def read_urlencoded(self): query = urllib.parse.parse_qsl( qs, self.keep_blank_values, self.strict_parsing, encoding=self.encoding, errors=self.errors, - max_num_fields=self.max_num_fields, separator=self.separator) + max_num_fields=self.max_num_fields) self.list = [MiniFieldStorage(key, value) for key, value in query] self.skip_lines() @@ -621,7 +602,7 @@ def read_multi(self, environ, keep_blank_values, strict_parsing): query = urllib.parse.parse_qsl( self.qs_on_post, self.keep_blank_values, self.strict_parsing, encoding=self.encoding, errors=self.errors, - max_num_fields=self.max_num_fields, separator=self.separator) + max_num_fields=self.max_num_fields) self.list.extend(MiniFieldStorage(key, value) for key, value in query) klass = self.FieldStorageClass or self.__class__ @@ -665,7 +646,7 @@ def read_multi(self, environ, keep_blank_values, strict_parsing): else self.limit - self.bytes_read part = klass(self.fp, headers, ib, environ, keep_blank_values, strict_parsing, limit, - self.encoding, self.errors, max_num_fields, self.separator) + self.encoding, self.errors, max_num_fields) if max_num_fields is not None: max_num_fields -= 1 @@ -755,8 +736,7 @@ def read_lines_to_outerboundary(self): last_line_lfend = True _read = 0 while 1: - - if self.limit is not None and 0 <= self.limit <= _read: + if self.limit is not None and _read >= self.limit: break line = self.fp.readline(1<<16) # bytes self.bytes_read += len(line) diff --git a/Lib/cgitb.py b/Lib/cgitb.py index 8ce0e833a9..4f81271be3 100644 --- a/Lib/cgitb.py +++ b/Lib/cgitb.py @@ -31,11 +31,6 @@ import time import tokenize import traceback -import warnings -from html import escape as html_escape - -warnings._deprecated(__name__, remove=(3, 13)) - def reset(): """Return a string that resets the CGI and browser to a known state.""" @@ -110,16 +105,10 @@ def html(einfo, context=5): etype = etype.__name__ pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable date = time.ctime(time.time()) - head = f''' - - - - - -
 
- 
-{html_escape(str(etype))}
-{pyver}
{date}
+ head = '' + pydoc.html.heading( + '%s' % + strong(pydoc.html.escape(str(etype))), + '#ffffff', '#6622aa', pyver + '
' + date) + '''

A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred.

''' @@ -192,8 +181,8 @@ def reader(lnum=[lnum]): diff --git a/Lib/chunk.py b/Lib/chunk.py index 618781efd1..d94dd39807 100644 --- a/Lib/chunk.py +++ b/Lib/chunk.py @@ -48,10 +48,6 @@ default is 1, i.e. aligned. """ -import warnings - -warnings._deprecated(__name__, remove=(3, 13)) - class Chunk: def __init__(self, file, align=True, bigendian=True, inclheader=False): import struct @@ -68,7 +64,7 @@ def __init__(self, file, align=True, bigendian=True, inclheader=False): try: self.chunksize = struct.unpack_from(strflag+'L', file.read(4))[0] except struct.error: - raise EOFError from None + raise EOFError if inclheader: self.chunksize = self.chunksize - 8 # subtract header self.size_read = 0 diff --git a/Lib/cmd.py b/Lib/cmd.py index 88ee7d3ddc..859e91096d 100644 --- a/Lib/cmd.py +++ b/Lib/cmd.py @@ -310,10 +310,10 @@ def do_help(self, arg): names = self.get_names() cmds_doc = [] cmds_undoc = [] - topics = set() + help = {} for name in names: if name[:5] == 'help_': - topics.add(name[5:]) + help[name[5:]]=1 names.sort() # There can be duplicates if routines overridden prevname = '' @@ -323,16 +323,16 @@ def do_help(self, arg): continue prevname = name cmd=name[3:] - if cmd in topics: + if cmd in help: cmds_doc.append(cmd) - topics.remove(cmd) + del help[cmd] elif getattr(self, name).__doc__: cmds_doc.append(cmd) else: cmds_undoc.append(cmd) self.stdout.write("%s\n"%str(self.doc_leader)) self.print_topics(self.doc_header, cmds_doc, 15,80) - self.print_topics(self.misc_header, sorted(topics),15,80) + self.print_topics(self.misc_header, list(help.keys()),15,80) self.print_topics(self.undoc_header, cmds_undoc, 15,80) def print_topics(self, header, cmds, cmdlen, maxcol): diff --git a/Lib/codeop.py b/Lib/codeop.py index 2213b69f23..e29c0b38c0 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -10,6 +10,30 @@ syntax error (OverflowError and ValueError can be produced by malformed literals). +Approach: + +First, check if the source consists entirely of blank lines and +comments; if so, replace it with 'pass', because the built-in +parser doesn't always do the right thing for these. + +Compile three times: as is, with \n, and with \n\n appended. If it +compiles as is, it's complete. If it compiles with one \n appended, +we expect more. If it doesn't compile either way, we compare the +error we get when compiling with \n or \n\n appended. If the errors +are the same, the code is broken. But if the errors are different, we +expect more. Not intuitive; not even guaranteed to hold in future +releases; but this matches the compiler's behavior from Python 1.4 +through 2.2, at least. + +Caveat: + +It is possible (but not likely) that the parser stops parsing with a +successful outcome before reaching the end of the source; in this +case, trailing symbols may be ignored instead of causing an error. +For example, a backslash followed by two newlines may be followed by +arbitrary garbage. This will be fixed once the API for the parser is +better. + The two interfaces are: compile_command(source, filename, symbol): @@ -40,50 +64,54 @@ __all__ = ["compile_command", "Compile", "CommandCompiler"] -# 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**. -PyCF_DONT_IMPLY_DEDENT = 0x200 -PyCF_ALLOW_INCOMPLETE_INPUT = 0x4000 +PyCF_DONT_IMPLY_DEDENT = 0x200 # Matches pythonrun.h + def _maybe_compile(compiler, source, filename, symbol): - # Check for source consisting of only blank lines and comments. + # Check for source consisting of only blank lines and comments for line in source.split("\n"): line = line.strip() if line and line[0] != '#': - break # Leave it alone. + break # Leave it alone else: if symbol != "eval": source = "pass" # Replace it with a 'pass' statement - # Disable compiler warnings when checking for incomplete input. + err = err1 = err2 = None + code = code1 = code2 = None + + try: + code = compiler(source, filename, symbol) + except SyntaxError: + pass + + # Catch syntax warnings after the first compile + # to emit warnings (SyntaxWarning, DeprecationWarning) at most once. with warnings.catch_warnings(): - warnings.simplefilter("ignore", (SyntaxWarning, DeprecationWarning)) + warnings.simplefilter("error") + + try: + code1 = compiler(source + "\n", filename, symbol) + except SyntaxError as e: + err1 = e + try: - compiler(source, filename, symbol) - except SyntaxError: # Let other compile() errors propagate. - try: - compiler(source + "\n", filename, symbol) - return None - except SyntaxError as e: - if "incomplete input" in str(e): - return None - # fallthrough - - return compiler(source, filename, symbol) - - -def _is_syntax_error(err1, err2): - rep1 = repr(err1) - rep2 = repr(err2) - if "was never closed" in rep1 and "was never closed" in rep2: - return False - if rep1 == rep2: - return True - return False + code2 = compiler(source + "\n\n", filename, symbol) + except SyntaxError as e: + err2 = e + + try: + if code: + return code + if not code1 and repr(err1) == repr(err2): + raise err1 + finally: + err1 = err2 = None + def _compile(source, filename, symbol): - return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT) + return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT) + def compile_command(source, filename="", symbol="single"): r"""Compile a command and determine whether it is incomplete. @@ -106,13 +134,15 @@ def compile_command(source, filename="", symbol="single"): """ return _maybe_compile(_compile, source, filename, symbol) + class Compile: """Instances of this class behave much like the built-in compile function, but if one is used to compile text containing a future statement, it "remembers" and compiles all subsequent program texts with the statement in force.""" + def __init__(self): - self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT + self.flags = PyCF_DONT_IMPLY_DEDENT def __call__(self, source, filename, symbol): codeob = compile(source, filename, symbol, self.flags, True) @@ -121,6 +151,7 @@ def __call__(self, source, filename, symbol): self.flags |= feature.compiler_flag return codeob + class CommandCompiler: """Instances of this class have __call__ methods identical in signature to compile_command; the difference is that if the diff --git a/Lib/colorsys.py b/Lib/colorsys.py index 9bdc83e377..12b432537b 100644 --- a/Lib/colorsys.py +++ b/Lib/colorsys.py @@ -1,14 +1,10 @@ """Conversion functions between RGB and other color systems. - This modules provides two functions for each color system ABC: - rgb_to_abc(r, g, b) --> a, b, c abc_to_rgb(a, b, c) --> r, g, b - All inputs and outputs are triples of floats in the range [0.0...1.0] (with the exception of I and Q, which covers a slightly larger range). Inputs outside the valid range may cause exceptions or invalid outputs. - Supported color systems: RGB: Red, Green, Blue components YIQ: Luminance, Chrominance (used by composite video signals) @@ -75,18 +71,17 @@ def yiq_to_rgb(y, i, q): def rgb_to_hls(r, g, b): maxc = max(r, g, b) minc = min(r, g, b) - sumc = (maxc+minc) - rangec = (maxc-minc) - l = sumc/2.0 + # XXX Can optimize (maxc+minc) and (maxc-minc) + l = (minc+maxc)/2.0 if minc == maxc: return 0.0, l, 0.0 if l <= 0.5: - s = rangec / sumc + s = (maxc-minc) / (maxc+minc) else: - s = rangec / (2.0-sumc) - rc = (maxc-r) / rangec - gc = (maxc-g) / rangec - bc = (maxc-b) / rangec + s = (maxc-minc) / (2.0-maxc-minc) + rc = (maxc-r) / (maxc-minc) + gc = (maxc-g) / (maxc-minc) + bc = (maxc-b) / (maxc-minc) if r == maxc: h = bc-gc elif g == maxc: @@ -125,14 +120,13 @@ def _v(m1, m2, hue): def rgb_to_hsv(r, g, b): maxc = max(r, g, b) minc = min(r, g, b) - rangec = (maxc-minc) v = maxc if minc == maxc: return 0.0, 0.0, v - s = rangec / maxc - rc = (maxc-r) / rangec - gc = (maxc-g) / rangec - bc = (maxc-b) / rangec + s = (maxc-minc) / maxc + rc = (maxc-r) / (maxc-minc) + gc = (maxc-g) / (maxc-minc) + bc = (maxc-b) / (maxc-minc) if r == maxc: h = bc-gc elif g == maxc: diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index 43164cff31..cc736572b0 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -1,3 +1,4 @@ +import cgi import os import sys import tempfile @@ -5,10 +6,6 @@ from collections import namedtuple from io import StringIO, BytesIO from test import support -from test.support import warnings_helper - -cgi = warnings_helper.import_deprecated("cgi") - class HackedSysModule: # The regression test will have real values in sys.argv, which @@ -53,7 +50,7 @@ def do_test(buf, method): return ComparableException(err) parse_strict_test_cases = [ - ("", {}), + ("", ValueError("bad query field: ''")), ("&", ValueError("bad query field: ''")), ("&&", ValueError("bad query field: ''")), # Should the next few really be valid? @@ -126,6 +123,8 @@ def test_parse_multipart(self): 'file': [b'Testing 123.\n'], 'title': ['']} self.assertEqual(result, expected) + # TODO: RUSTPYTHON + @unittest.expectedFailure def test_parse_multipart_without_content_length(self): POSTDATA = '''--JfISa01 Content-Disposition: form-data; name="submit-name" @@ -175,8 +174,6 @@ def test_fieldstorage_invalid(self): fs = cgi.FieldStorage(headers={'content-type':'text/plain'}) self.assertRaises(TypeError, bool, fs) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_strict(self): for orig, expect in parse_strict_test_cases: # Test basic parsing @@ -203,6 +200,8 @@ def test_strict(self): else: self.assertEqual(fs.getvalue(key), expect_val[0]) + # TODO: RUSTPYTHON + @unittest.expectedFailure def test_separator(self): parse_semicolon = [ ("x=1;y=2.0", {'x': ['1'], 'y': ['2.0']}), @@ -227,7 +226,6 @@ def test_separator(self): else: self.assertEqual(fs.getvalue(key), expect_val[0]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_log(self): cgi.log("Testing") @@ -580,9 +578,8 @@ def test_parse_header(self): ("form-data", {"name": "files", "filename": 'fo"o;bar'})) def test_all(self): - not_exported = { - "logfile", "logfp", "initlog", "dolog", "nolog", "closelog", "log", - "maxlen", "valid_boundary"} + not_exported = {"logfile", "logfp", "initlog", "dolog", "nolog", + "closelog", "log", "maxlen", "valid_boundary"} support.check__all__(self, cgi, not_exported=not_exported) diff --git a/Lib/test/test_cgitb.py b/Lib/test/test_cgitb.py index 501c7fcce2..5cbb054a3c 100644 --- a/Lib/test/test_cgitb.py +++ b/Lib/test/test_cgitb.py @@ -1,9 +1,8 @@ from test.support.os_helper import temp_dir from test.support.script_helper import assert_python_failure -from test.support.warnings_helper import import_deprecated import unittest import sys -cgitb = import_deprecated("cgitb") +import cgitb class TestCgitb(unittest.TestCase): @@ -32,7 +31,7 @@ def test_html(self): def test_text(self): try: raise ValueError("Hello World") - except ValueError: + except ValueError as err: text = cgitb.text(sys.exc_info()) self.assertIn("ValueError", text) self.assertIn("Hello World", text) @@ -42,9 +41,8 @@ def test_syshook_no_logdir_default_format(self): rc, out, err = assert_python_failure( '-c', ('import cgitb; cgitb.enable(logdir=%s); ' - 'raise ValueError("Hello World")') % repr(tracedir), - PYTHONIOENCODING='utf-8') - out = out.decode() + 'raise ValueError("Hello World")') % repr(tracedir)) + out = out.decode(sys.getfilesystemencoding()) self.assertIn("ValueError", out) self.assertIn("Hello World", out) self.assertIn("<module>", out) @@ -58,9 +56,8 @@ def test_syshook_no_logdir_text_format(self): rc, out, err = assert_python_failure( '-c', ('import cgitb; cgitb.enable(format="text", logdir=%s); ' - 'raise ValueError("Hello World")') % repr(tracedir), - PYTHONIOENCODING='utf-8') - out = out.decode() + 'raise ValueError("Hello World")') % repr(tracedir)) + out = out.decode(sys.getfilesystemencoding()) self.assertIn("ValueError", out) self.assertIn("Hello World", out) self.assertNotIn('

', out) diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py index 319801c71f..c9ffad485f 100644 --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -6,10 +6,10 @@ import cmd import sys -import doctest import unittest import io from test import support +from test.support import import_helper class samplecmdclass(cmd.Cmd): """ @@ -70,7 +70,7 @@ class samplecmdclass(cmd.Cmd): >>> mycmd.complete_help("12") [] >>> sorted(mycmd.complete_help("")) - ['add', 'exit', 'help', 'life', 'meaning', 'shell'] + ['add', 'exit', 'help', 'shell'] Test for the function do_help(): >>> mycmd.do_help("testet") @@ -79,20 +79,12 @@ class samplecmdclass(cmd.Cmd): help text for add >>> mycmd.onecmd("help add") help text for add - >>> mycmd.onecmd("help meaning") # doctest: +NORMALIZE_WHITESPACE - Try and be nice to people, avoid eating fat, read a good book every - now and then, get some walking in, and try to live together in peace - and harmony with people of all creeds and nations. >>> mycmd.do_help("") Documented commands (type help ): ======================================== add help - Miscellaneous help topics: - ========================== - life meaning - Undocumented commands: ====================== exit shell @@ -123,22 +115,17 @@ class samplecmdclass(cmd.Cmd): This test includes the preloop(), postloop(), default(), emptyline(), parseline(), do_help() functions >>> mycmd.use_rawinput=0 - - >>> mycmd.cmdqueue=["add", "add 4 5", "", "help", "help add", "exit"] - >>> mycmd.cmdloop() # doctest: +REPORT_NDIFF + >>> mycmd.cmdqueue=["", "add", "add 4 5", "help", "help add","exit"] + >>> mycmd.cmdloop() Hello from preloop + help text for add *** invalid number of arguments 9 - 9 Documented commands (type help ): ======================================== add help - Miscellaneous help topics: - ========================== - life meaning - Undocumented commands: ====================== exit shell @@ -178,17 +165,6 @@ def help_add(self): print("help text for add") return - def help_meaning(self): - print("Try and be nice to people, avoid eating fat, read a " - "good book every now and then, get some walking in, " - "and try to live together in peace and harmony with " - "people of all creeds and nations.") - return - - def help_life(self): - print("Always look on the bright side of life") - return - def do_exit(self, arg): return True @@ -244,12 +220,13 @@ def test_input_reset_at_EOF(self): "(Cmd) *** Unknown syntax: EOF\n")) -def load_tests(loader, tests, pattern): - tests.addTest(doctest.DocTestSuite()) - return tests +def test_main(verbose=None): + from test import test_cmd + support.run_doctest(test_cmd, verbose) + support.run_unittest(TestAlternateInput) def test_coverage(coverdir): - trace = support.import_module('trace') + trace = import_helper.import_module('trace') tracer=trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], trace=0, count=1) tracer.run('import importlib; importlib.reload(cmd); test_main()') @@ -263,4 +240,4 @@ def test_coverage(coverdir): elif "-i" in sys.argv: samplecmdclass().cmdloop() else: - unittest.main() + test_main() diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 51c834d798..40313cb399 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -757,6 +757,8 @@ def check_different_constants(const1, const2): self.assertTrue(f1(0)) self.assertTrue(f2(0.0)) + # TODO: RUSTPYTHON + @unittest.expectedFailure def test_path_like_objects(self): # An implicit test for PyUnicode_FSDecoder(). compile("42", FakePath("test_compile_pathlike"), "single") diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 142fa04e38..c5788fca2c 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -1694,6 +1694,8 @@ class TestExamples(unittest.TestCase): def test_accumulate(self): self.assertEqual(list(accumulate([1,2,3,4,5])), [1, 3, 6, 10, 15]) + # TODO: RUSTPYTHON + @unittest.expectedFailure def test_accumulate_reducible(self): # check copy, deepcopy, pickle data = [1, 2, 3, 4, 5] diff --git a/Lib/test/test_opcode.py b/Lib/test/test_opcode.py deleted file mode 100644 index 170eb1cb1d..0000000000 --- a/Lib/test/test_opcode.py +++ /dev/null @@ -1,356 +0,0 @@ -""" - Test cases for codeop.py - Nick Mathewson -""" -import sys -import unittest -import warnings -from test import support -from test.support import warnings_helper - -from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT -import io - -if support.is_jython: - - def unify_callables(d): - for n,v in d.items(): - if hasattr(v, '__call__'): - d[n] = True - return d - -class CodeopTests(unittest.TestCase): - - def assertValid(self, str, symbol='single'): - '''succeed iff str is a valid piece of code''' - if support.is_jython: - code = compile_command(str, "", symbol) - self.assertTrue(code) - if symbol == "single": - d,r = {},{} - saved_stdout = sys.stdout - sys.stdout = io.StringIO() - try: - exec(code, d) - exec(compile(str,"","single"), r) - finally: - sys.stdout = saved_stdout - elif symbol == 'eval': - ctx = {'a': 2} - d = { 'value': eval(code,ctx) } - r = { 'value': eval(str,ctx) } - self.assertEqual(unify_callables(r),unify_callables(d)) - else: - expected = compile(str, "", symbol, PyCF_DONT_IMPLY_DEDENT) - self.assertEqual(compile_command(str, "", symbol), expected) - - def assertIncomplete(self, str, symbol='single'): - '''succeed iff str is the start of a valid piece of code''' - self.assertEqual(compile_command(str, symbol=symbol), None) - - def assertInvalid(self, str, symbol='single', is_syntax=1): - '''succeed iff str is the start of an invalid piece of code''' - try: - compile_command(str,symbol=symbol) - self.fail("No exception raised for invalid code") - except SyntaxError: - self.assertTrue(is_syntax) - except OverflowError: - self.assertTrue(not is_syntax) - - # TODO: RUSTPYTHON - @unittest.expectedFailure - def test_valid(self): - av = self.assertValid - - # special case - if not support.is_jython: - self.assertEqual(compile_command(""), - compile("pass", "", 'single', - PyCF_DONT_IMPLY_DEDENT)) - self.assertEqual(compile_command("\n"), - compile("pass", "", 'single', - PyCF_DONT_IMPLY_DEDENT)) - else: - av("") - av("\n") - - av("a = 1") - av("\na = 1") - av("a = 1\n") - av("a = 1\n\n") - av("\n\na = 1\n\n") - - av("def x():\n pass\n") - av("if 1:\n pass\n") - - av("\n\nif 1: pass\n") - av("\n\nif 1: pass\n\n") - - av("def x():\n\n pass\n") - av("def x():\n pass\n \n") - av("def x():\n pass\n \n") - - av("pass\n") - av("3**3\n") - - av("if 9==3:\n pass\nelse:\n pass\n") - av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n") - - av("#a\n#b\na = 3\n") - av("#a\n\n \na=3\n") - av("a=3\n\n") - av("a = 9+ \\\n3") - - av("3**3","eval") - av("(lambda z: \n z**3)","eval") - - av("9+ \\\n3","eval") - av("9+ \\\n3\n","eval") - - av("\n\na**3","eval") - av("\n \na**3","eval") - av("#a\n#b\na**3","eval") - - av("\n\na = 1\n\n") - av("\n\nif 1: a=1\n\n") - - av("if 1:\n pass\n if 1:\n pass\n else:\n pass\n") - av("#a\n\n \na=3\n\n") - - av("\n\na**3","eval") - av("\n \na**3","eval") - av("#a\n#b\na**3","eval") - - av("def f():\n try: pass\n finally: [x for x in (1,2)]\n") - av("def f():\n pass\n#foo\n") - av("@a.b.c\ndef f():\n pass\n") - - # TODO: RUSTPYTHON - @unittest.expectedFailure - def test_incomplete(self): - ai = self.assertIncomplete - - ai("(a **") - ai("(a,b,") - ai("(a,b,(") - ai("(a,b,(") - ai("a = (") - ai("a = {") - ai("b + {") - - ai("print([1,\n2,") - ai("print({1:1,\n2:3,") - ai("print((1,\n2,") - - ai("if 9==3:\n pass\nelse:") - ai("if 9==3:\n pass\nelse:\n") - ai("if 9==3:\n pass\nelse:\n pass") - ai("if 1:") - ai("if 1:\n") - ai("if 1:\n pass\n if 1:\n pass\n else:") - ai("if 1:\n pass\n if 1:\n pass\n else:\n") - ai("if 1:\n pass\n if 1:\n pass\n else:\n pass") - - ai("def x():") - ai("def x():\n") - ai("def x():\n\n") - - ai("def x():\n pass") - ai("def x():\n pass\n ") - ai("def x():\n pass\n ") - ai("\n\ndef x():\n pass") - - ai("a = 9+ \\") - ai("a = 'a\\") - ai("a = '''xy") - - ai("","eval") - ai("\n","eval") - ai("(","eval") - ai("(9+","eval") - ai("9+ \\","eval") - ai("lambda z: \\","eval") - - ai("if True:\n if True:\n if True: \n") - - ai("@a(") - ai("@a(b") - ai("@a(b,") - ai("@a(b,c") - ai("@a(b,c,") - - ai("from a import (") - ai("from a import (b") - ai("from a import (b,") - ai("from a import (b,c") - ai("from a import (b,c,") - - ai("[") - ai("[a") - ai("[a,") - ai("[a,b") - ai("[a,b,") - - ai("{") - ai("{a") - ai("{a:") - ai("{a:b") - ai("{a:b,") - ai("{a:b,c") - ai("{a:b,c:") - ai("{a:b,c:d") - ai("{a:b,c:d,") - - ai("a(") - ai("a(b") - ai("a(b,") - ai("a(b,c") - ai("a(b,c,") - - ai("a[") - ai("a[b") - ai("a[b,") - ai("a[b:") - ai("a[b:c") - ai("a[b:c:") - ai("a[b:c:d") - - ai("def a(") - ai("def a(b") - ai("def a(b,") - ai("def a(b,c") - ai("def a(b,c,") - - ai("(") - ai("(a") - ai("(a,") - ai("(a,b") - ai("(a,b,") - - ai("if a:\n pass\nelif b:") - ai("if a:\n pass\nelif b:\n pass\nelse:") - - ai("while a:") - ai("while a:\n pass\nelse:") - - ai("for a in b:") - ai("for a in b:\n pass\nelse:") - - ai("try:") - ai("try:\n pass\nexcept:") - ai("try:\n pass\nfinally:") - ai("try:\n pass\nexcept:\n pass\nfinally:") - - ai("with a:") - ai("with a as b:") - - ai("class a:") - ai("class a(") - ai("class a(b") - ai("class a(b,") - ai("class a():") - - ai("[x for") - ai("[x for x in") - ai("[x for x in (") - - ai("(x for") - ai("(x for x in") - ai("(x for x in (") - - def test_invalid(self): - ai = self.assertInvalid - ai("a b") - - ai("a @") - ai("a b @") - ai("a ** @") - - ai("a = ") - ai("a = 9 +") - - ai("def x():\n\npass\n") - - ai("\n\n if 1: pass\n\npass") - - ai("a = 9+ \\\n") - ai("a = 'a\\ ") - ai("a = 'a\\\n") - - ai("a = 1","eval") - ai("]","eval") - ai("())","eval") - ai("[}","eval") - ai("9+","eval") - ai("lambda z:","eval") - ai("a b","eval") - - ai("return 2.3") - ai("if (a == 1 and b = 2): pass") - - ai("del 1") - ai("del (1,)") - ai("del [1]") - ai("del '1'") - - ai("[i for i in range(10)] = (1, 2, 3)") - - def test_invalid_exec(self): - ai = self.assertInvalid - ai("raise = 4", symbol="exec") - ai('def a-b', symbol='exec') - ai('await?', symbol='exec') - ai('=!=', symbol='exec') - ai('a await raise b', symbol='exec') - ai('a await raise b?+1', symbol='exec') - - def test_filename(self): - self.assertEqual(compile_command("a = 1\n", "abc").co_filename, - compile("a = 1\n", "abc", 'single').co_filename) - self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename, - compile("a = 1\n", "def", 'single').co_filename) - - # TODO: RUSTPYTHON - @unittest.expectedFailure - def test_warning(self): - # Test that the warning is only returned once. - with warnings_helper.check_warnings( - (".*literal", SyntaxWarning), - (".*invalid", DeprecationWarning), - ) as w: - compile_command(r"'\e' is 0") - self.assertEqual(len(w.warnings), 2) - - # bpo-41520: check SyntaxWarning treated as an SyntaxError - with warnings.catch_warnings(), self.assertRaises(SyntaxError): - warnings.simplefilter('error', SyntaxWarning) - compile_command('1 is 1', symbol='exec') - - # Check DeprecationWarning treated as an SyntaxError - with warnings.catch_warnings(), self.assertRaises(SyntaxError): - warnings.simplefilter('error', DeprecationWarning) - compile_command(r"'\e'", symbol='exec') - - # TODO: RUSTPYTHON - @unittest.expectedFailure - def test_incomplete_warning(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - self.assertIncomplete("'\\e' + (") - self.assertEqual(w, []) - - # TODO: RUSTPYTHON - @unittest.expectedFailure - def test_invalid_warning(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - self.assertInvalid("'\\e' 1") - self.assertEqual(len(w), 1) - self.assertEqual(w[0].category, DeprecationWarning) - self.assertRegex(str(w[0].message), 'invalid escape sequence') - self.assertEqual(w[0].filename, '') - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index c6d4cfe5c6..e4c4e0d3b4 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -801,6 +801,8 @@ def test_integer_notations(self): value = plistlib.loads(pl) self.assertEqual(value, 123) + # TODO: RUSTPYTHON + @unittest.expectedFailure def test_xml_encodings(self): base = TESTDATA[plistlib.FMT_XML] diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index b2fee6207b..2d87370d92 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -656,6 +656,8 @@ def test_basic_script(self): self._check_script(script_name, "", script_name, script_name, expect_spec=False) + # TODO: RUSTPYTHON + @unittest.expectedFailure def test_basic_script_with_path_object(self): with temp_dir() as script_dir: mod_name = 'script' diff --git a/Lib/warnings.py b/Lib/warnings.py index 7d8c440012..81f9864778 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -33,8 +33,9 @@ def _showwarnmsg_impl(msg): pass def _formatwarnmsg_impl(msg): - category = msg.category.__name__ - s = f"{msg.filename}:{msg.lineno}: {category}: {msg.message}\n" + s = ("%s:%s: %s: %s\n" + % (msg.filename, msg.lineno, msg.category.__name__, + msg.message)) if msg.line is None: try: @@ -54,20 +55,11 @@ def _formatwarnmsg_impl(msg): if msg.source is not None: try: import tracemalloc - # Logging a warning should not raise a new exception: - # catch Exception, not only ImportError and RecursionError. + tb = tracemalloc.get_object_traceback(msg.source) except Exception: - # don't suggest to enable tracemalloc if it's not available - tracing = True + # When a warning is logged during Python shutdown, tracemalloc + # and the import machinery don't work anymore tb = None - else: - tracing = tracemalloc.is_tracing() - try: - tb = tracemalloc.get_object_traceback(msg.source) - except Exception: - # When a warning is logged during Python shutdown, tracemalloc - # and the import machinery don't work anymore - tb = None if tb is not None: s += 'Object allocated at (most recent call last):\n' @@ -85,9 +77,6 @@ def _formatwarnmsg_impl(msg): if line: line = line.strip() s += ' %s\n' % line - elif not tracing: - s += (f'{category}: Enable tracemalloc to get the object ' - f'allocation traceback\n') return s # Keep a reference to check if the function was replaced @@ -124,7 +113,7 @@ def _formatwarnmsg(msg): if fw is not _formatwarning_orig: # warnings.formatwarning() was replaced return fw(msg.message, msg.category, - msg.filename, msg.lineno, msg.line) + msg.filename, msg.lineno, line=msg.line) return _formatwarnmsg_impl(msg) def filterwarnings(action, message="", category=Warning, module="", lineno=0, @@ -211,6 +200,7 @@ def _processoptions(args): # Helper for _processoptions() def _setoption(arg): + import re parts = arg.split(':') if len(parts) > 5: raise _OptionError("too many fields (max 5): %r" % (arg,)) @@ -219,13 +209,11 @@ def _setoption(arg): action, message, category, module, lineno = [s.strip() for s in parts] action = _getaction(action) + message = re.escape(message) category = _getcategory(category) - if message or module: - import re - if message: - message = re.escape(message) + module = re.escape(module) if module: - module = re.escape(module) + r'\Z' + module = module + '$' if lineno: try: lineno = int(lineno) @@ -249,21 +237,26 @@ def _getaction(action): # Helper for _setoption() def _getcategory(category): + import re if not category: return Warning - if '.' not in category: - import builtins as m - klass = category + if re.match("^[a-zA-Z0-9_]+$", category): + try: + cat = eval(category) + except NameError: + raise _OptionError("unknown warning category: %r" % (category,)) from None else: - module, _, klass = category.rpartition('.') + i = category.rfind(".") + module = category[:i] + klass = category[i+1:] try: m = __import__(module, None, None, [klass]) except ImportError: raise _OptionError("invalid module name: %r" % (module,)) from None - try: - cat = getattr(m, klass) - except AttributeError: - raise _OptionError("unknown warning category: %r" % (category,)) from None + try: + cat = getattr(m, klass) + except AttributeError: + raise _OptionError("unknown warning category: %r" % (category,)) from None if not issubclass(cat, Warning): raise _OptionError("invalid warning category: %r" % (category,)) return cat @@ -310,16 +303,28 @@ def warn(message, category=None, stacklevel=1, source=None): raise ValueError except ValueError: globals = sys.__dict__ - filename = "sys" lineno = 1 else: globals = frame.f_globals - filename = frame.f_code.co_filename lineno = frame.f_lineno if '__name__' in globals: module = globals['__name__'] else: module = "" + filename = globals.get('__file__') + if filename: + fnl = filename.lower() + if fnl.endswith(".pyc"): + filename = filename[:-1] + else: + if module == "__main__": + try: + filename = sys.argv[0] + except AttributeError: + # embedded interpreters don't have sys.argv, see bug #839151 + filename = '__main__' + if not filename: + filename = module registry = globals.setdefault("__warningregistry__", {}) warn_explicit(message, category, filename, lineno, module, registry, globals, source) @@ -432,13 +437,9 @@ class catch_warnings(object): named 'warnings' and imported under that name. This argument is only useful when testing the warnings module itself. - If the 'action' argument is not None, the remaining arguments are passed - to warnings.simplefilter() as if it were called immediately on entering the - context. """ - def __init__(self, *, record=False, module=None, - action=None, category=Warning, lineno=0, append=False): + def __init__(self, *, record=False, module=None): """Specify whether to record warnings and if an alternative module should be used other than sys.modules['warnings']. @@ -449,10 +450,6 @@ def __init__(self, *, record=False, module=None, self._record = record self._module = sys.modules['warnings'] if module is None else module self._entered = False - if action is None: - self._filter = None - else: - self._filter = (action, category, lineno, append) def __repr__(self): args = [] @@ -472,8 +469,6 @@ def __enter__(self): self._module._filters_mutated() self._showwarning = self._module.showwarning self._showwarnmsg_impl = self._module._showwarnmsg_impl - if self._filter is not None: - simplefilter(*self._filter) if self._record: log = [] self._module._showwarnmsg_impl = log.append @@ -493,27 +488,6 @@ def __exit__(self, *exc_info): self._module._showwarnmsg_impl = self._showwarnmsg_impl -_DEPRECATED_MSG = "{name!r} is deprecated and slated for removal in Python {remove}" - -def _deprecated(name, message=_DEPRECATED_MSG, *, remove, _version=sys.version_info): - """Warn that *name* is deprecated or should be removed. - - RuntimeError is raised if *remove* specifies a major/minor tuple older than - the current Python version or the same version but past the alpha. - - The *message* argument is formatted with *name* and *remove* as a Python - version (e.g. "3.11"). - - """ - remove_formatted = f"{remove[0]}.{remove[1]}" - if (_version[:2] > remove) or (_version[:2] == remove and _version[3] != "alpha"): - msg = f"{name!r} was slated for removal after Python {remove_formatted} alpha" - raise RuntimeError(msg) - else: - msg = message.format(name=name, remove=remove_formatted) - warn(msg, DeprecationWarning, stacklevel=3) - - # Private utility function called by _PyErr_WarnUnawaitedCoroutine def _warn_unawaited_coroutine(coro): msg_lines = [ diff --git a/README.md b/README.md index 2c8266cb12..ef3e60f34d 100644 --- a/README.md +++ b/README.md @@ -205,8 +205,6 @@ cargo doc --no-deps --all # Excluding all dependencies Documentation HTML files can then be found in the `target/doc` directory or you can append `--open` to the previous commands to have the documentation open automatically on your default browser. -For a high level overview of the components, see the [architecture](architecture/architecture.md) document. - ## Contributing Contributions are more than welcome, and in many cases we are happy to guide diff --git a/architecture/architecture.md b/architecture/architecture.md deleted file mode 100644 index 5b1ae9cc68..0000000000 --- a/architecture/architecture.md +++ /dev/null @@ -1,150 +0,0 @@ -# Architecture - -This document contains a high-level architectural overview of RustPython, thus it's very well-suited to get to know [the codebase][1]. - -RustPython is an Open Source (MIT-licensed) Python 3 interpreter written in Rust, available as both a library and a shell environment. Using Rust to implement the Python interpreter enables Python to be used as a programming language for Rust applications. Moreover, it allows Python to be immediately compiled in the browser using WebAssembly, meaning that anyone could easily run their Python code in the browser. For a more detailed introduction to RustPython, have a look at [this blog post][2]. - -RustPython consists of several components which are described in the section below. Take a look at [this video][3] for a brief walk-through of the components of RustPython. For a more elaborate introduction to one of these components, the parser, see [this blog post][4] for more information. - -Have a look at these websites for a demo of RustPython running in the browser using WebAssembly: - -- [The demo page.][5] -- [The RustPython Notebook, a toy notebook inspired by the Iodide project.][6] - -If, after reading this, you want to contribute to RustPython, take a look at these sources to get to know how and where to start: - -- [RustPython Development Guide and Tips][7] -- [How to contribute to RustPython using CPython's unit tests][8] - -## Bird's eye view - -A high-level overview of the workings of RustPython is visible in the figure below, showing how Python source files are interpreted. - -![overview.png](overview.png) - -Main architecture of RustPython. - -The RustPython interpreter can be decoupled into three distinct components: the parser, compiler and VM. - -1. The parser is responsible for converting the source code into tokens, and deriving an Abstract Syntax Tree (AST) from it. -2. The compiler converts the generated AST to bytecode. -3. The VM then executes the bytecode given user supplied input parameters and returns its result. - -## Entry points - -The main entry point of RustPython is located in `src/main.rs` and simply forwards a call to `run`, located in [`src/lib.rs`][9]. This method will call the compiler, which in turn will call the parser, and pass the compiled bytecode to the VM. - -For each of the three components, the entry point is as follows: - -- Parser: The Parser is located in a separate project, [RustPython/Parser][10]. See the documentation there for more information. -- Compiler: `compile`, located in [`vm/src/vm/compile.rs`][11], this eventually forwards a call to [`compiler::compile`][12]. -- VM: `run_code_obj`, located in [`vm/src/vm/mod.rs`][13]. This creates a new frame in which the bytecode is executed. - -## Components - -Here we give a brief overview of each component and its function. For more details for the separate crates please take a look at their respective READMEs. - -### Compiler - -This component, implemented as the `rustpython-compiler/` package, is responsible for translating a Python source file into its equivalent bytecode representation. As an example, the following Python file: - -```python -def f(x): - return x + 1 -``` - -Is compiled to the following bytecode: - -```python - 2 0 LoadFast (0, x) - 1 LoadConst (1) - 2 BinaryOperation (Add) - 3 ReturnValue -``` - -Note that bytecode is subject to change, and is _not_ a stable interface. - -#### Parser - -The Parser is the main sub-component of the compiler. All the functionality required for parsing Python sourcecode to an abstract syntax tree (AST) is implemented here:generator. - -1. Lexical Analysis -2. Parsing - -The functionality for parsing resides in the RustPython/Parser project. See the documentation there for more information. - -### VM - -The Virtual Machine (VM) is responsible for executing the bytecode generated by the compiler. It is implemented in the `rustpython-vm/` package. The VM is currently implemented as a stack machine, meaning that it uses a stack to store intermediate results. In the `rustpython-vm/` package, additional sub-components are present, for example: - -- builtins: the built in objects of Python, such as `int` and `str`. -- stdlib: parts of the standard library that contains built-in modules needed for the VM to function, such as `sys`. - -## Additional packages - -### common - -The `rustpython-common` package contains functionality that is not directly coupled to one of the other RustPython packages. For example, the [`float_ops.rs`][14] file contains operations on floating point numbers -which could be used by other projects if needed. - -### derive and derive-impl - -Rust language extensions and macros specific to RustPython. Here we can find the definition of `PyModule` and `PyClass` along with useful macros like `py_compile!`. - -### jit - -This folder contains a _very_ experimental JIT implementation. - -### stdlib - -Part of the Python standard library that's implemented in Rust. The modules that live here are ones that aren't needed for the VM to function, but are useful for the user. For example, the `random` module is implemented here. - -### Lib - -Python side of the standard libary, copied over (with care) from CPython sourcecode. - -#### Lib/test - -CPython test suite, which can be used to compare with CPython in terms of conformance. -Many of these files have been modified to fit with the current state of RustPython (when they were added), in one of three ways: - -- The test has been commented out completely if the parser could not create a valid code object. If a file is unable to be parsed - the test suite would not be able to run at all. -- A test has been marked as `unittest.skip("TODO: RustPython ")` if it led to a crash of RustPython. Adding a reason - is useful to know why the test was skipped but not mandatory. -- A test has been marked as `unittest.expectedFailure` with a `TODO: RustPython ` comment left on top of the decorator. This decorator is used if the test can run but the result differs from what is expected. - -Note: This is a recommended route to starting with contributing. To get started please take a look [this blog post][15]. - -### src - -The RustPython executable/REPL (Read-Eval-Print-Loop) is implemented here, which is the interface through which users come in contact with library. -Some things to note: - -- The CLI is defined in the [`run` function of `src/lib.rs`][16]. -- The interface and helper for the REPL are defined in this package, but the actual REPL can be found in `vm/src/readline.rs` - -### WASM - -Crate for WebAssembly build, which compiles the RustPython package to a format that can be run on any modern browser. - -### extra_tests - -Integration and snippets that test for additional edge-cases, implementation specific functionality and bug report snippets. - -[1]: https://github.com/RustPython/RustPython -[2]: https://2021.desosa.nl/projects/rustpython/posts/vision/ -[3]: https://www.youtube.com/watch?v=nJDY9ASuiLc&t=213s -[4]: https://rustpython.github.io/2020/04/02/thing-explainer-parser.html -[5]: https://rustpython.github.io/demo/ -[6]: https://rustpython.github.io/demo/notebook/ -[7]: https://github.com/RustPython/RustPython/blob/master/DEVELOPMENT.md -[8]: https://rustpython.github.io/guideline/2020/04/04/how-to-contribute-by-cpython-unittest.html -[9]: https://github.com/RustPython/RustPython/blob/0e24cf48c63ae4ca9f829e88142a987cab3a9966/src/lib.rs#L63 -[10]: https://github.com/RustPython/Parser -[11]: https://github.com/RustPython/RustPython/blob/0e24cf48c63ae4ca9f829e88142a987cab3a9966/vm/src/vm/compile.rs#LL10C17-L10C17 -[12]: https://github.com/RustPython/RustPython/blob/0e24cf48c63ae4ca9f829e88142a987cab3a9966/vm/src/vm/compile.rs#L26 -[13]: https://github.com/RustPython/RustPython/blob/0e24cf48c63ae4ca9f829e88142a987cab3a9966/vm/src/vm/mod.rs#L356 -[14]: https://github.com/RustPython/RustPython/blob/0e24cf48c63ae4ca9f829e88142a987cab3a9966/common/src/float_ops.rs -[15]: https://rustpython.github.io/guideline/2020/04/04/how-to-contribute-by-cpython-unittest.html -[16]: https://github.com/RustPython/RustPython/blob/0e24cf48c63ae4ca9f829e88142a987cab3a9966/src/lib.rs#L63 diff --git a/architecture/overview.png b/architecture/overview.png deleted file mode 100644 index ce66706f3c83ebe48d4df1a796723a8aa9ffde4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35246 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 (f64, i32) { /// # Examples /// /// ``` -/// use malachite_bigint::BigInt; +/// use num_bigint::BigInt; /// use rustpython_common::float_ops::eq_int; /// let a = 1.0f64; /// let b = BigInt::from(1); diff --git a/common/src/hash.rs b/common/src/hash.rs index 6169003ab1..4e123bce13 100644 --- a/common/src/hash.rs +++ b/common/src/hash.rs @@ -1,4 +1,4 @@ -use malachite_bigint::BigInt; +use num_bigint::BigInt; use num_traits::ToPrimitive; use siphasher::sip::SipHasher24; use std::hash::{BuildHasher, Hash, Hasher}; diff --git a/common/src/int.rs b/common/src/int.rs index c968d747ef..193d714351 100644 --- a/common/src/int.rs +++ b/common/src/int.rs @@ -1,34 +1,6 @@ use bstr::ByteSlice; -use malachite_base::{num::conversion::traits::RoundingInto, rounding_modes::RoundingMode}; -use malachite_bigint::{BigInt, BigUint, Sign}; -use malachite_q::Rational; -use num_traits::{One, ToPrimitive, Zero}; - -pub fn true_div(numerator: &BigInt, denominator: &BigInt) -> f64 { - let val: f64 = Rational::from_integers_ref(numerator.into(), denominator.into()) - .rounding_into(RoundingMode::Nearest); - - if val == f64::MAX || val == f64::MIN { - // FIXME: not possible for available ratio? - return f64::INFINITY; - } - val -} - -pub fn float_to_ratio(value: f64) -> Option<(BigInt, BigInt)> { - let sign = match std::cmp::PartialOrd::partial_cmp(&value, &0.0)? { - std::cmp::Ordering::Less => Sign::Minus, - std::cmp::Ordering::Equal => return Some((BigInt::zero(), BigInt::one())), - std::cmp::Ordering::Greater => Sign::Plus, - }; - Rational::try_from(value).ok().map(|x| { - let (numer, denom) = x.into_numerator_and_denominator(); - ( - BigInt::from_biguint(sign, numer.into()), - BigUint::from(denom).into(), - ) - }) -} +use num_bigint::{BigInt, BigUint, Sign}; +use num_traits::{ToPrimitive, Zero}; pub fn bytes_to_int(lit: &[u8], mut base: u32) -> Option { // split sign diff --git a/compiler/codegen/src/compile.rs b/compiler/codegen/src/compile.rs index bd0e934737..67f9003db3 100644 --- a/compiler/codegen/src/compile.rs +++ b/compiler/codegen/src/compile.rs @@ -927,30 +927,31 @@ impl Compiler { name: &str, args: &located_ast::Arguments, ) -> CompileResult { - let defaults: Vec<_> = args.defaults().collect(); - let have_defaults = !defaults.is_empty(); + let have_defaults = !args.defaults.is_empty(); if have_defaults { // Construct a tuple: - let size = defaults.len().to_u32(); - for element in &defaults { + let size = args.defaults.len().to_u32(); + for element in &args.defaults { self.compile_expression(element)?; } emit!(self, Instruction::BuildTuple { size }); } - let (kw_without_defaults, kw_with_defaults) = args.split_kwonlyargs(); - if !kw_with_defaults.is_empty() { - let default_kw_count = kw_with_defaults.len(); - for (arg, default) in kw_with_defaults.iter() { + if !args.kw_defaults.is_empty() { + let required_kw_count = args.kwonlyargs.len().saturating_sub(args.kw_defaults.len()); + for (kw, default) in args.kwonlyargs[required_kw_count..] + .iter() + .zip(&args.kw_defaults) + { self.emit_constant(ConstantData::Str { - value: arg.arg.to_string(), + value: kw.arg.to_string(), }); self.compile_expression(default)?; } emit!( self, Instruction::BuildMap { - size: default_kw_count.to_u32(), + size: args.kw_defaults.len().to_u32(), } ); } @@ -959,7 +960,7 @@ impl Compiler { if have_defaults { func_flags |= bytecode::MakeFunctionFlags::DEFAULTS; } - if !kw_with_defaults.is_empty() { + if !args.kw_defaults.is_empty() { func_flags |= bytecode::MakeFunctionFlags::KW_ONLY_DEFAULTS; } @@ -974,9 +975,7 @@ impl Compiler { let args_iter = std::iter::empty() .chain(&args.posonlyargs) .chain(&args.args) - .map(|arg| arg.as_arg()) - .chain(kw_without_defaults.into_iter()) - .chain(kw_with_defaults.into_iter().map(|(arg, _)| arg)); + .chain(&args.kwonlyargs); for name in args_iter { self.varname(name.arg.as_str())?; } @@ -1229,7 +1228,6 @@ impl Compiler { .chain(&args.posonlyargs) .chain(&args.args) .chain(&args.kwonlyargs) - .map(|arg| arg.as_arg()) .chain(args.vararg.as_deref()) .chain(args.kwarg.as_deref()); for arg in args_iter { @@ -2942,10 +2940,10 @@ impl ToU32 for usize { mod tests { use super::*; use rustpython_parser as parser; - use rustpython_parser_core::source_code::LinearLocator; + use rustpython_parser_core::source_code::SourceLocator; fn compile_exec(source: &str) -> CodeObject { - let mut locator: LinearLocator = LinearLocator::new(source); + let mut locator: SourceLocator = SourceLocator::new(source); use rustpython_parser::ast::fold::Fold; let mut compiler: Compiler = Compiler::new( CompileOpts::default(), diff --git a/compiler/codegen/src/symboltable.rs b/compiler/codegen/src/symboltable.rs index 216d1af782..aeba6739a1 100644 --- a/compiler/codegen/src/symboltable.rs +++ b/compiler/codegen/src/symboltable.rs @@ -599,17 +599,9 @@ impl SymbolTableBuilder { Ok(()) } - fn scan_parameters( - &mut self, - parameters: &[ast::located::ArgWithDefault], - ) -> SymbolTableResult { + fn scan_parameters(&mut self, parameters: &[ast::located::Arg]) -> SymbolTableResult { for parameter in parameters { - let usage = if parameter.def.annotation.is_some() { - SymbolUsage::AnnotationParameter - } else { - SymbolUsage::Parameter - }; - self.register_name(parameter.def.arg.as_str(), usage, parameter.def.location())?; + self.scan_parameter(parameter)?; } Ok(()) } @@ -623,6 +615,23 @@ impl SymbolTableBuilder { self.register_name(parameter.arg.as_str(), usage, parameter.location()) } + fn scan_parameters_annotations( + &mut self, + parameters: &[ast::located::Arg], + ) -> SymbolTableResult { + for parameter in parameters { + self.scan_parameter_annotation(parameter)?; + } + Ok(()) + } + + fn scan_parameter_annotation(&mut self, parameter: &ast::located::Arg) -> SymbolTableResult { + if let Some(annotation) = ¶meter.annotation { + self.scan_annotation(annotation)?; + } + Ok(()) + } + fn scan_annotation(&mut self, annotation: &ast::located::Expr) -> SymbolTableResult { if self.future_annotations { Ok(()) @@ -1192,31 +1201,20 @@ impl SymbolTableBuilder { line_number: LineNumber, ) -> SymbolTableResult { // Evaluate eventual default parameters: - for default in args - .posonlyargs - .iter() - .chain(args.args.iter()) - .chain(args.kwonlyargs.iter()) - .filter_map(|arg| arg.default.as_ref()) - { - self.scan_expression(default, ExpressionContext::Load)?; // not ExprContext? + self.scan_expressions(&args.defaults, ExpressionContext::Load)?; + for expression in args.kw_defaults.iter() { + self.scan_expression(expression, ExpressionContext::Load)?; } // Annotations are scanned in outer scope: - for annotation in args - .posonlyargs - .iter() - .chain(args.args.iter()) - .chain(args.kwonlyargs.iter()) - .filter_map(|arg| arg.def.annotation.as_ref()) - { - self.scan_annotation(annotation)?; - } - if let Some(annotation) = args.vararg.as_ref().and_then(|arg| arg.annotation.as_ref()) { - self.scan_annotation(annotation)?; + self.scan_parameters_annotations(&args.posonlyargs)?; + self.scan_parameters_annotations(&args.args)?; + self.scan_parameters_annotations(&args.kwonlyargs)?; + if let Some(name) = &args.vararg { + self.scan_parameter_annotation(name)?; } - if let Some(annotation) = args.kwarg.as_ref().and_then(|arg| arg.annotation.as_ref()) { - self.scan_annotation(annotation)?; + if let Some(name) = &args.kwarg { + self.scan_parameter_annotation(name)?; } self.enter_scope(name, SymbolTableType::Function, line_number.get()); diff --git a/compiler/core/Cargo.toml b/compiler/core/Cargo.toml index 4fc05510be..30d74d62df 100644 --- a/compiler/core/Cargo.toml +++ b/compiler/core/Cargo.toml @@ -12,7 +12,7 @@ rustpython-parser-core = { workspace = true } bitflags = { workspace = true } itertools = { workspace = true } -malachite-bigint = { workspace = true } +num-bigint = { workspace = true } num-complex = { workspace = true } serde = { version = "1.0.133", optional = true, default-features = false, features = ["derive"] } diff --git a/compiler/core/src/bytecode.rs b/compiler/core/src/bytecode.rs index 8ada60a9e6..7c313cbeb6 100644 --- a/compiler/core/src/bytecode.rs +++ b/compiler/core/src/bytecode.rs @@ -3,7 +3,7 @@ use bitflags::bitflags; use itertools::Itertools; -use malachite_bigint::BigInt; +use num_bigint::BigInt; use num_complex::Complex64; use rustpython_parser_core::source_code::{OneIndexed, SourceLocation}; use std::marker::PhantomData; diff --git a/compiler/core/src/marshal.rs b/compiler/core/src/marshal.rs index a5d3089ff6..c49bb77663 100644 --- a/compiler/core/src/marshal.rs +++ b/compiler/core/src/marshal.rs @@ -1,5 +1,5 @@ use crate::bytecode::*; -use malachite_bigint::{BigInt, Sign}; +use num_bigint::{BigInt, Sign}; use num_complex::Complex64; use rustpython_parser_core::source_code::{OneIndexed, SourceLocation}; use std::convert::Infallible; diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index c281058555..ae79d0ae12 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -1,9 +1,9 @@ use rustpython_codegen::{compile, symboltable}; -use rustpython_parser::ast::{self as ast, fold::Fold, ConstantOptimizer}; +use rustpython_parser::ast::{fold::Fold, ConstantOptimizer}; pub use rustpython_codegen::compile::CompileOpts; pub use rustpython_compiler_core::{bytecode::CodeObject, Mode}; -pub use rustpython_parser::{source_code::LinearLocator, Parse}; +pub use rustpython_parser::source_code::SourceLocator; // these modules are out of repository. re-exporting them here for convenience. pub use rustpython_codegen as codegen; @@ -52,7 +52,7 @@ pub fn compile( source_path: String, opts: CompileOpts, ) -> Result { - let mut locator = LinearLocator::new(source); + let mut locator = SourceLocator::new(source); let mut ast = match parser::parse(source, mode.into(), &source_path) { Ok(x) => x, Err(e) => return Err(locator.locate_error(e)), @@ -71,17 +71,17 @@ pub fn compile_symtable( mode: Mode, source_path: &str, ) -> Result { - let mut locator = LinearLocator::new(source); + let mut locator = SourceLocator::new(source); let res = match mode { Mode::Exec | Mode::Single | Mode::BlockExpr => { let ast = - ast::Suite::parse(source, source_path).map_err(|e| locator.locate_error(e))?; + parser::parse_program(source, source_path).map_err(|e| locator.locate_error(e))?; let ast = locator.fold(ast).unwrap(); symboltable::SymbolTable::scan_program(&ast) } Mode::Eval => { - let expr = - ast::Expr::parse(source, source_path).map_err(|e| locator.locate_error(e))?; + let expr = parser::parse_expression(source, source_path) + .map_err(|e| locator.locate_error(e))?; let expr = locator.fold(expr).unwrap(); symboltable::SymbolTable::scan_expr(&expr) } diff --git a/extra_tests/snippets/stdlib_os.py b/extra_tests/snippets/stdlib_os.py index 849fc238a8..203472fe02 100644 --- a/extra_tests/snippets/stdlib_os.py +++ b/extra_tests/snippets/stdlib_os.py @@ -32,7 +32,6 @@ assert os.read(src_fd, src_len) == os.read(dest_fd, bytes_sent) os.close(src_fd) os.close(dest_fd) - os.remove('destination.md') try: os.open('DOES_NOT_EXIST', 0) diff --git a/scripts/cargo-llvm-cov.py b/scripts/cargo-llvm-cov.py deleted file mode 100644 index a77d56a87c..0000000000 --- a/scripts/cargo-llvm-cov.py +++ /dev/null @@ -1,20 +0,0 @@ -import os -import subprocess - -TARGET = "extra_tests/snippets" - -def run_llvm_cov(file_path: str): - """ 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. """ - 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) \ No newline at end of file diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index b9224655f8..f53eb49211 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -27,8 +27,9 @@ itertools = { workspace = true } libc = { workspace = true } nix = { workspace = true } num-complex = { workspace = true } -malachite-bigint = { workspace = true } +num-bigint = { workspace = true } num-integer = { workspace = true } +num-rational = { workspace = true } num-traits = { workspace = true } num_enum = { workspace = true } once_cell = { workspace = true } @@ -40,7 +41,7 @@ csv-core = "0.1.10" dyn-clone = "1.0.10" libz-sys = { version = "1.1.5", optional = true } puruspe = "0.1.5" -xml-rs = "0.8.14" +xml-rs = "0.8.4" # random rand = { workspace = true } @@ -114,4 +115,4 @@ features = [ ] [target.'cfg(target_os = "macos")'.dependencies] -system-configuration = "0.5.0" +system-configuration = "0.5.0" \ No newline at end of file diff --git a/stdlib/src/json.rs b/stdlib/src/json.rs index 921e545e5d..450930e6ac 100644 --- a/stdlib/src/json.rs +++ b/stdlib/src/json.rs @@ -12,7 +12,7 @@ mod _json { types::{Callable, Constructor}, AsObject, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; - use malachite_bigint::BigInt; + use num_bigint::BigInt; use std::str::FromStr; #[pyattr(name = "make_scanner")] diff --git a/stdlib/src/math.rs b/stdlib/src/math.rs index bc977e2a53..ea3c93a750 100644 --- a/stdlib/src/math.rs +++ b/stdlib/src/math.rs @@ -8,9 +8,10 @@ mod math { identifier, PyObject, PyObjectRef, PyRef, PyResult, VirtualMachine, }; use itertools::Itertools; - use malachite_bigint::BigInt; - use num_traits::{One, Signed, Zero}; - use rustpython_common::{float_ops, int::true_div}; + use num_bigint::BigInt; + use num_rational::Ratio; + use num_traits::{One, Signed, ToPrimitive, Zero}; + use rustpython_common::float_ops; use std::cmp::Ordering; // Constants @@ -153,8 +154,8 @@ mod math { // If we set 2^n to be the greatest power of 2 below x, then x/2^n is in [1, 2), and can // thus be converted into a float. let n = x.bits() as u32 - 1; - let frac = true_div(x, &BigInt::from(2).pow(n)); - f64::from(n) + frac.log2() + let frac = Ratio::new(x.clone(), BigInt::from(2).pow(n)); + f64::from(n) + frac.to_f64().unwrap().log2() } #[pyfunction] diff --git a/stdlib/src/random.rs b/stdlib/src/random.rs index 1dfc4fcc30..950d34ee90 100644 --- a/stdlib/src/random.rs +++ b/stdlib/src/random.rs @@ -11,7 +11,7 @@ mod _random { types::Constructor, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; - use malachite_bigint::{BigInt, BigUint, Sign}; + use num_bigint::{BigInt, Sign}; use num_traits::{Signed, Zero}; use rand::{rngs::StdRng, RngCore, SeedableRng}; @@ -140,7 +140,7 @@ mod _random { }) .collect::>(); - let uint = BigUint::new(wordarray); + let uint = num_bigint::BigUint::new(wordarray); // very unlikely but might as well check let sign = if uint.is_zero() { Sign::NoSign diff --git a/stdlib/src/resource.rs b/stdlib/src/resource.rs index 85ba5d7be2..51f2fd7857 100644 --- a/stdlib/src/resource.rs +++ b/stdlib/src/resource.rs @@ -149,8 +149,7 @@ mod resource { #[pyfunction] fn getrlimit(resource: i32, vm: &VirtualMachine) -> PyResult { - #[allow(clippy::unnecessary_cast)] - if resource < 0 || resource >= RLIM_NLIMITS as i32 { + if resource < 0 || resource >= RLIM_NLIMITS as _ { return Err(vm.new_value_error("invalid resource specified".to_owned())); } let rlimit = unsafe { @@ -165,8 +164,7 @@ mod resource { #[pyfunction] fn setrlimit(resource: i32, limits: Limits, vm: &VirtualMachine) -> PyResult<()> { - #[allow(clippy::unnecessary_cast)] - if resource < 0 || resource >= RLIM_NLIMITS as i32 { + if resource < 0 || resource >= RLIM_NLIMITS as _ { return Err(vm.new_value_error("invalid resource specified".to_owned())); } let res = unsafe { diff --git a/stdlib/src/sqlite.rs b/stdlib/src/sqlite.rs index cb8c5f89cb..32ea0d0cd5 100644 --- a/stdlib/src/sqlite.rs +++ b/stdlib/src/sqlite.rs @@ -45,7 +45,6 @@ mod _sqlite { SQLITE_NULL, SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE, SQLITE_OPEN_URI, SQLITE_TEXT, SQLITE_TRACE_STMT, SQLITE_TRANSIENT, SQLITE_UTF8, }; - use malachite_bigint::Sign; use rustpython_common::{ atomic::{Ordering, PyAtomic, Radium}, hash::PyHash, @@ -481,9 +480,9 @@ mod _sqlite { }; let val = match val?.as_bigint().sign() { - Sign::Plus => 1, - Sign::Minus => -1, - Sign::NoSign => 0, + num_bigint::Sign::Plus => 1, + num_bigint::Sign::Minus => -1, + num_bigint::Sign::NoSign => 0, }; Ok(val) diff --git a/vm/Cargo.toml b/vm/Cargo.toml index d25096bd4e..d594d6e0af 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -52,9 +52,10 @@ itertools = { workspace = true } libc = { workspace = true } log = { workspace = true } nix = { workspace = true } -malachite-bigint = { workspace = true } +num-bigint = { workspace = true } num-complex = { workspace = true } num-integer = { workspace = true } +num-rational = { workspace = true } num-traits = { workspace = true } num_enum = { workspace = true } once_cell = { workspace = true } diff --git a/vm/src/buffer.rs b/vm/src/buffer.rs index 2b61ee629d..f053c510cc 100644 --- a/vm/src/buffer.rs +++ b/vm/src/buffer.rs @@ -7,7 +7,7 @@ use crate::{ }; use half::f16; use itertools::Itertools; -use malachite_bigint::BigInt; +use num_bigint::BigInt; use num_traits::{PrimInt, ToPrimitive}; use std::{fmt, iter::Peekable, mem, os::raw}; diff --git a/vm/src/builtins/bool.rs b/vm/src/builtins/bool.rs index b3cb20238e..60a3947491 100644 --- a/vm/src/builtins/bool.rs +++ b/vm/src/builtins/bool.rs @@ -9,7 +9,7 @@ use crate::{ AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, TryFromBorrowedObject, VirtualMachine, }; -use malachite_bigint::Sign; +use num_bigint::Sign; use num_traits::Zero; use rustpython_format::FormatSpec; use std::fmt::{Debug, Formatter}; diff --git a/vm/src/builtins/code.rs b/vm/src/builtins/code.rs index bedd71f241..79fc86a138 100644 --- a/vm/src/builtins/code.rs +++ b/vm/src/builtins/code.rs @@ -14,7 +14,6 @@ use crate::{ types::Representable, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; -use malachite_bigint::BigInt; use num_traits::Zero; use std::{borrow::Borrow, fmt, ops::Deref}; @@ -152,7 +151,7 @@ impl ConstantBag for PyObjBag<'_> { self.0.intern_str(name) } - fn make_int(&self, value: BigInt) -> Self::Constant { + fn make_int(&self, value: num_bigint::BigInt) -> Self::Constant { Literal(self.0.new_int(value).into()) } diff --git a/vm/src/builtins/enumerate.rs b/vm/src/builtins/enumerate.rs index 64d7c1ed36..00a3215ad6 100644 --- a/vm/src/builtins/enumerate.rs +++ b/vm/src/builtins/enumerate.rs @@ -10,7 +10,7 @@ use crate::{ types::{Constructor, IterNext, Iterable, SelfIter}, AsObject, Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; -use malachite_bigint::BigInt; +use num_bigint::BigInt; use num_traits::Zero; #[pyclass(module = false, name = "enumerate", traverse)] diff --git a/vm/src/builtins/float.rs b/vm/src/builtins/float.rs index 1cd041b7b9..f389c4e7ee 100644 --- a/vm/src/builtins/float.rs +++ b/vm/src/builtins/float.rs @@ -17,10 +17,10 @@ use crate::{ AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject, TryFromObject, VirtualMachine, }; -use malachite_bigint::{BigInt, ToBigInt}; +use num_bigint::{BigInt, ToBigInt}; use num_complex::Complex64; +use num_rational::Ratio; use num_traits::{Signed, ToPrimitive, Zero}; -use rustpython_common::int::float_to_ratio; use rustpython_format::FormatSpec; #[pyclass(module = false, name = "float")] @@ -458,18 +458,20 @@ impl PyFloat { #[pymethod] fn as_integer_ratio(&self, vm: &VirtualMachine) -> PyResult<(PyIntRef, PyIntRef)> { let value = self.value; + if !value.is_finite() { + return Err(if value.is_infinite() { + vm.new_overflow_error("cannot convert Infinity to integer ratio".to_owned()) + } else if value.is_nan() { + vm.new_value_error("cannot convert NaN to integer ratio".to_owned()) + } else { + unreachable!("it must be finite") + }); + } - float_to_ratio(value) - .map(|(numer, denom)| (vm.ctx.new_bigint(&numer), vm.ctx.new_bigint(&denom))) - .ok_or_else(|| { - if value.is_infinite() { - vm.new_overflow_error("cannot convert Infinity to integer ratio".to_owned()) - } else if value.is_nan() { - vm.new_value_error("cannot convert NaN to integer ratio".to_owned()) - } else { - unreachable!("finite float must able to convert to integer ratio") - } - }) + let ratio = Ratio::from_float(value).unwrap(); + let numer = vm.ctx.new_bigint(ratio.numer()); + let denom = vm.ctx.new_bigint(ratio.denom()); + Ok((numer, denom)) } #[pyclassmethod] diff --git a/vm/src/builtins/int.rs b/vm/src/builtins/int.rs index 9b25a504fc..a9e9d962c7 100644 --- a/vm/src/builtins/int.rs +++ b/vm/src/builtins/int.rs @@ -5,7 +5,7 @@ use crate::{ class::PyClassImpl, common::{ hash, - int::{bigint_to_finite_float, bytes_to_int, true_div}, + int::{bigint_to_finite_float, bytes_to_int}, }, convert::{IntoPyException, ToPyObject, ToPyResult}, function::{ @@ -17,12 +17,13 @@ use crate::{ AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, TryFromBorrowedObject, VirtualMachine, }; -use malachite_bigint::{BigInt, Sign}; +use num_bigint::{BigInt, Sign}; use num_integer::Integer; +use num_rational::Ratio; use num_traits::{One, Pow, PrimInt, Signed, ToPrimitive, Zero}; use rustpython_format::FormatSpec; -use std::fmt; -use std::ops::{Neg, Not}; +use std::ops::{Div, Neg}; +use std::{fmt, ops::Not}; #[pyclass(module = false, name = "int")] #[derive(Debug)] @@ -196,7 +197,7 @@ fn inner_truediv(i1: &BigInt, i2: &BigInt, vm: &VirtualMachine) -> PyResult { return Err(vm.new_zero_division_error("division by zero".to_owned())); } - let float = true_div(i1, i2); + let float = Ratio::from(i1.clone()).div(i2).to_f64().unwrap(); if float.is_infinite() { Err(vm.new_exception_msg( @@ -276,7 +277,7 @@ impl PyInt { out = out.wrapping_shl(32) | digit; } match v.sign() { - Sign::Minus => out * -1i32 as u32, + num_bigint::Sign::Minus => out * -1i32 as u32, _ => out, } }) diff --git a/vm/src/builtins/range.rs b/vm/src/builtins/range.rs index 1543e2e564..276c94c1d0 100644 --- a/vm/src/builtins/range.rs +++ b/vm/src/builtins/range.rs @@ -15,7 +15,7 @@ use crate::{ VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; -use malachite_bigint::{BigInt, Sign}; +use num_bigint::{BigInt, Sign}; use num_integer::Integer; use num_traits::{One, Signed, ToPrimitive, Zero}; use once_cell::sync::Lazy; diff --git a/vm/src/builtins/slice.rs b/vm/src/builtins/slice.rs index e06aee682e..5dbf960c40 100644 --- a/vm/src/builtins/slice.rs +++ b/vm/src/builtins/slice.rs @@ -9,7 +9,7 @@ use crate::{ types::{Comparable, Constructor, PyComparisonOp, Representable}, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; -use malachite_bigint::{BigInt, ToBigInt}; +use num_bigint::{BigInt, ToBigInt}; use num_traits::{One, Signed, Zero}; #[pyclass(module = false, name = "slice", unhashable = true, traverse)] diff --git a/vm/src/bytesinner.rs b/vm/src/bytesinner.rs index 750344c781..dee1934816 100644 --- a/vm/src/bytesinner.rs +++ b/vm/src/bytesinner.rs @@ -17,7 +17,7 @@ use crate::{ }; use bstr::ByteSlice; use itertools::Itertools; -use malachite_bigint::BigInt; +use num_bigint::BigInt; use num_traits::ToPrimitive; #[derive(Debug, Default, Clone)] diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index f8aeb3f6da..5e5ae9d583 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -655,7 +655,7 @@ impl Dict { } pub fn pop_back(&self) -> Option<(PyObjectRef, T)> { - let inner = &mut *self.write(); + let mut inner = &mut *self.write(); let entry = loop { let entry = inner.entries.pop()?; if let Some(entry) = entry { diff --git a/vm/src/function/number.rs b/vm/src/function/number.rs index 5f23543395..4292b82a06 100644 --- a/vm/src/function/number.rs +++ b/vm/src/function/number.rs @@ -1,6 +1,6 @@ use super::argument::OptionalArg; use crate::{builtins::PyIntRef, AsObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine}; -use malachite_bigint::BigInt; +use num_bigint::BigInt; use num_complex::Complex64; use num_traits::PrimInt; use std::ops::Deref; diff --git a/vm/src/macros.rs b/vm/src/macros.rs index c058764f38..6e1953436c 100644 --- a/vm/src/macros.rs +++ b/vm/src/macros.rs @@ -64,7 +64,7 @@ macro_rules! py_namespace { /// # Examples /// /// ``` -/// use malachite_bigint::ToBigInt; +/// use num_bigint::ToBigInt; /// use num_traits::Zero; /// /// use rustpython_vm::match_class; @@ -88,7 +88,7 @@ macro_rules! py_namespace { /// With a binding to the downcasted type: /// /// ``` -/// use malachite_bigint::ToBigInt; +/// use num_bigint::ToBigInt; /// use num_traits::Zero; /// /// use rustpython_vm::match_class; diff --git a/vm/src/sliceable.rs b/vm/src/sliceable.rs index 257d325651..7a4a3d0b5a 100644 --- a/vm/src/sliceable.rs +++ b/vm/src/sliceable.rs @@ -3,7 +3,7 @@ use crate::{ builtins::{int::PyInt, slice::PySlice}, PyObject, PyResult, VirtualMachine, }; -use malachite_bigint::BigInt; +use num_bigint::BigInt; use num_traits::{Signed, ToPrimitive}; use std::ops::Range; diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index bf34528e2c..ec2be4b7a4 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -11,7 +11,7 @@ use crate::{ compiler::core::bytecode::OpArgType, compiler::CompileError, convert::ToPyException, - source_code::{LinearLocator, OneIndexed, SourceLocation, SourceRange}, + source_code::{OneIndexed, SourceLocation, SourceLocator, SourceRange}, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; @@ -99,6 +99,10 @@ trait Node: Sized { fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult; } +trait NamedNode: Node { + const NAME: &'static str; +} + impl Node for Vec { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { vm.ctx @@ -313,23 +317,13 @@ impl Node for ast::ConversionFlag { } } -impl Node for ast::located::Arguments { - fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { - self.into_python_arguments().ast_to_object(vm) - } - fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult { - ast::located::PythonArguments::ast_from_object(vm, object) - .map(ast::located::PythonArguments::into_arguments) - } -} - #[cfg(feature = "rustpython-parser")] pub(crate) fn parse( vm: &VirtualMachine, source: &str, mode: parser::Mode, ) -> Result { - let mut locator = LinearLocator::new(source); + let mut locator = SourceLocator::new(source); let top = parser::parse(source, mode, "").map_err(|e| locator.locate_error(e))?; let top = locator.fold_mod(top).unwrap(); Ok(top.ast_to_object(vm)) diff --git a/vm/src/stdlib/ast/gen.rs b/vm/src/stdlib/ast/gen.rs index c189a78cce..3bb3d5008c 100644 --- a/vm/src/stdlib/ast/gen.rs +++ b/vm/src/stdlib/ast/gen.rs @@ -2215,6 +2215,9 @@ impl NodeTypeIgnoreTypeIgnore { } } +impl NamedNode for ast::located::Mod { + const NAME: &'static str = "mod"; +} // sum impl Node for ast::located::Mod { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -2250,6 +2253,9 @@ impl Node for ast::located::Mod { } } // constructor +impl NamedNode for ast::located::ModModule { + const NAME: &'static str = "Module"; +} impl Node for ast::located::ModModule { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ModModule { @@ -2278,6 +2284,9 @@ impl Node for ast::located::ModModule { } } // constructor +impl NamedNode for ast::located::ModInteractive { + const NAME: &'static str = "Interactive"; +} impl Node for ast::located::ModInteractive { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ModInteractive { @@ -2302,6 +2311,9 @@ impl Node for ast::located::ModInteractive { } } // constructor +impl NamedNode for ast::located::ModExpression { + const NAME: &'static str = "Expression"; +} impl Node for ast::located::ModExpression { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ModExpression { @@ -2323,6 +2335,9 @@ impl Node for ast::located::ModExpression { } } // constructor +impl NamedNode for ast::located::ModFunctionType { + const NAME: &'static str = "FunctionType"; +} impl Node for ast::located::ModFunctionType { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ModFunctionType { @@ -2354,6 +2369,9 @@ impl Node for ast::located::ModFunctionType { }) } } +impl NamedNode for ast::located::Stmt { + const NAME: &'static str = "stmt"; +} // sum impl Node for ast::located::Stmt { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -2464,6 +2482,9 @@ impl Node for ast::located::Stmt { } } // constructor +impl NamedNode for ast::located::StmtFunctionDef { + const NAME: &'static str = "FunctionDef"; +} impl Node for ast::located::StmtFunctionDef { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtFunctionDef { @@ -2520,6 +2541,9 @@ impl Node for ast::located::StmtFunctionDef { } } // constructor +impl NamedNode for ast::located::StmtAsyncFunctionDef { + const NAME: &'static str = "AsyncFunctionDef"; +} impl Node for ast::located::StmtAsyncFunctionDef { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtAsyncFunctionDef { @@ -2576,6 +2600,9 @@ impl Node for ast::located::StmtAsyncFunctionDef { } } // constructor +impl NamedNode for ast::located::StmtClassDef { + const NAME: &'static str = "ClassDef"; +} impl Node for ast::located::StmtClassDef { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtClassDef { @@ -2619,6 +2646,9 @@ impl Node for ast::located::StmtClassDef { } } // constructor +impl NamedNode for ast::located::StmtReturn { + const NAME: &'static str = "Return"; +} impl Node for ast::located::StmtReturn { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtReturn { @@ -2644,6 +2674,9 @@ impl Node for ast::located::StmtReturn { } } // constructor +impl NamedNode for ast::located::StmtDelete { + const NAME: &'static str = "Delete"; +} impl Node for ast::located::StmtDelete { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtDelete { @@ -2670,6 +2703,9 @@ impl Node for ast::located::StmtDelete { } } // constructor +impl NamedNode for ast::located::StmtAssign { + const NAME: &'static str = "Assign"; +} impl Node for ast::located::StmtAssign { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtAssign { @@ -2706,6 +2742,9 @@ impl Node for ast::located::StmtAssign { } } // constructor +impl NamedNode for ast::located::StmtAugAssign { + const NAME: &'static str = "AugAssign"; +} impl Node for ast::located::StmtAugAssign { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtAugAssign { @@ -2742,6 +2781,9 @@ impl Node for ast::located::StmtAugAssign { } } // constructor +impl NamedNode for ast::located::StmtAnnAssign { + const NAME: &'static str = "AnnAssign"; +} impl Node for ast::located::StmtAnnAssign { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtAnnAssign { @@ -2788,6 +2830,9 @@ impl Node for ast::located::StmtAnnAssign { } } // constructor +impl NamedNode for ast::located::StmtFor { + const NAME: &'static str = "For"; +} impl Node for ast::located::StmtFor { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtFor { @@ -2827,6 +2872,9 @@ impl Node for ast::located::StmtFor { } } // constructor +impl NamedNode for ast::located::StmtAsyncFor { + const NAME: &'static str = "AsyncFor"; +} impl Node for ast::located::StmtAsyncFor { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtAsyncFor { @@ -2872,6 +2920,9 @@ impl Node for ast::located::StmtAsyncFor { } } // constructor +impl NamedNode for ast::located::StmtWhile { + const NAME: &'static str = "While"; +} impl Node for ast::located::StmtWhile { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtWhile { @@ -2901,6 +2952,9 @@ impl Node for ast::located::StmtWhile { } } // constructor +impl NamedNode for ast::located::StmtIf { + const NAME: &'static str = "If"; +} impl Node for ast::located::StmtIf { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtIf { @@ -2930,6 +2984,9 @@ impl Node for ast::located::StmtIf { } } // constructor +impl NamedNode for ast::located::StmtWith { + const NAME: &'static str = "With"; +} impl Node for ast::located::StmtWith { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtWith { @@ -2962,6 +3019,9 @@ impl Node for ast::located::StmtWith { } } // constructor +impl NamedNode for ast::located::StmtAsyncWith { + const NAME: &'static str = "AsyncWith"; +} impl Node for ast::located::StmtAsyncWith { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtAsyncWith { @@ -2997,6 +3057,9 @@ impl Node for ast::located::StmtAsyncWith { } } // constructor +impl NamedNode for ast::located::StmtMatch { + const NAME: &'static str = "Match"; +} impl Node for ast::located::StmtMatch { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtMatch { @@ -3027,6 +3090,9 @@ impl Node for ast::located::StmtMatch { } } // constructor +impl NamedNode for ast::located::StmtRaise { + const NAME: &'static str = "Raise"; +} impl Node for ast::located::StmtRaise { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtRaise { @@ -3057,6 +3123,9 @@ impl Node for ast::located::StmtRaise { } } // constructor +impl NamedNode for ast::located::StmtTry { + const NAME: &'static str = "Try"; +} impl Node for ast::located::StmtTry { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtTry { @@ -3097,6 +3166,9 @@ impl Node for ast::located::StmtTry { } } // constructor +impl NamedNode for ast::located::StmtTryStar { + const NAME: &'static str = "TryStar"; +} impl Node for ast::located::StmtTryStar { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtTryStar { @@ -3140,6 +3212,9 @@ impl Node for ast::located::StmtTryStar { } } // constructor +impl NamedNode for ast::located::StmtAssert { + const NAME: &'static str = "Assert"; +} impl Node for ast::located::StmtAssert { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtAssert { @@ -3167,6 +3242,9 @@ impl Node for ast::located::StmtAssert { } } // constructor +impl NamedNode for ast::located::StmtImport { + const NAME: &'static str = "Import"; +} impl Node for ast::located::StmtImport { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtImport { @@ -3190,6 +3268,9 @@ impl Node for ast::located::StmtImport { } } // constructor +impl NamedNode for ast::located::StmtImportFrom { + const NAME: &'static str = "ImportFrom"; +} impl Node for ast::located::StmtImportFrom { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtImportFrom { @@ -3228,6 +3309,9 @@ impl Node for ast::located::StmtImportFrom { } } // constructor +impl NamedNode for ast::located::StmtGlobal { + const NAME: &'static str = "Global"; +} impl Node for ast::located::StmtGlobal { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtGlobal { @@ -3251,6 +3335,9 @@ impl Node for ast::located::StmtGlobal { } } // constructor +impl NamedNode for ast::located::StmtNonlocal { + const NAME: &'static str = "Nonlocal"; +} impl Node for ast::located::StmtNonlocal { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtNonlocal { @@ -3274,6 +3361,9 @@ impl Node for ast::located::StmtNonlocal { } } // constructor +impl NamedNode for ast::located::StmtExpr { + const NAME: &'static str = "Expr"; +} impl Node for ast::located::StmtExpr { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtExpr { @@ -3297,6 +3387,9 @@ impl Node for ast::located::StmtExpr { } } // constructor +impl NamedNode for ast::located::StmtPass { + const NAME: &'static str = "Pass"; +} impl Node for ast::located::StmtPass { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtPass { range: _range } = self; @@ -3314,6 +3407,9 @@ impl Node for ast::located::StmtPass { } } // constructor +impl NamedNode for ast::located::StmtBreak { + const NAME: &'static str = "Break"; +} impl Node for ast::located::StmtBreak { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtBreak { range: _range } = self; @@ -3331,6 +3427,9 @@ impl Node for ast::located::StmtBreak { } } // constructor +impl NamedNode for ast::located::StmtContinue { + const NAME: &'static str = "Continue"; +} impl Node for ast::located::StmtContinue { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtContinue { range: _range } = self; @@ -3347,6 +3446,9 @@ impl Node for ast::located::StmtContinue { }) } } +impl NamedNode for ast::located::Expr { + const NAME: &'static str = "expr"; +} // sum impl Node for ast::located::Expr { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -3459,6 +3561,9 @@ impl Node for ast::located::Expr { } } // constructor +impl NamedNode for ast::located::ExprBoolOp { + const NAME: &'static str = "BoolOp"; +} impl Node for ast::located::ExprBoolOp { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprBoolOp { @@ -3485,6 +3590,9 @@ impl Node for ast::located::ExprBoolOp { } } // constructor +impl NamedNode for ast::located::ExprNamedExpr { + const NAME: &'static str = "NamedExpr"; +} impl Node for ast::located::ExprNamedExpr { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprNamedExpr { @@ -3518,6 +3626,9 @@ impl Node for ast::located::ExprNamedExpr { } } // constructor +impl NamedNode for ast::located::ExprBinOp { + const NAME: &'static str = "BinOp"; +} impl Node for ast::located::ExprBinOp { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprBinOp { @@ -3547,6 +3658,9 @@ impl Node for ast::located::ExprBinOp { } } // constructor +impl NamedNode for ast::located::ExprUnaryOp { + const NAME: &'static str = "UnaryOp"; +} impl Node for ast::located::ExprUnaryOp { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprUnaryOp { @@ -3576,6 +3690,9 @@ impl Node for ast::located::ExprUnaryOp { } } // constructor +impl NamedNode for ast::located::ExprLambda { + const NAME: &'static str = "Lambda"; +} impl Node for ast::located::ExprLambda { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprLambda { @@ -3601,6 +3718,9 @@ impl Node for ast::located::ExprLambda { } } // constructor +impl NamedNode for ast::located::ExprIfExp { + const NAME: &'static str = "IfExp"; +} impl Node for ast::located::ExprIfExp { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprIfExp { @@ -3630,6 +3750,9 @@ impl Node for ast::located::ExprIfExp { } } // constructor +impl NamedNode for ast::located::ExprDict { + const NAME: &'static str = "Dict"; +} impl Node for ast::located::ExprDict { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprDict { @@ -3656,6 +3779,9 @@ impl Node for ast::located::ExprDict { } } // constructor +impl NamedNode for ast::located::ExprSet { + const NAME: &'static str = "Set"; +} impl Node for ast::located::ExprSet { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprSet { @@ -3678,6 +3804,9 @@ impl Node for ast::located::ExprSet { } } // constructor +impl NamedNode for ast::located::ExprListComp { + const NAME: &'static str = "ListComp"; +} impl Node for ast::located::ExprListComp { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprListComp { @@ -3707,6 +3836,9 @@ impl Node for ast::located::ExprListComp { } } // constructor +impl NamedNode for ast::located::ExprSetComp { + const NAME: &'static str = "SetComp"; +} impl Node for ast::located::ExprSetComp { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprSetComp { @@ -3736,6 +3868,9 @@ impl Node for ast::located::ExprSetComp { } } // constructor +impl NamedNode for ast::located::ExprDictComp { + const NAME: &'static str = "DictComp"; +} impl Node for ast::located::ExprDictComp { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprDictComp { @@ -3769,6 +3904,9 @@ impl Node for ast::located::ExprDictComp { } } // constructor +impl NamedNode for ast::located::ExprGeneratorExp { + const NAME: &'static str = "GeneratorExp"; +} impl Node for ast::located::ExprGeneratorExp { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprGeneratorExp { @@ -3798,6 +3936,9 @@ impl Node for ast::located::ExprGeneratorExp { } } // constructor +impl NamedNode for ast::located::ExprAwait { + const NAME: &'static str = "Await"; +} impl Node for ast::located::ExprAwait { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprAwait { @@ -3821,6 +3962,9 @@ impl Node for ast::located::ExprAwait { } } // constructor +impl NamedNode for ast::located::ExprYield { + const NAME: &'static str = "Yield"; +} impl Node for ast::located::ExprYield { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprYield { @@ -3846,6 +3990,9 @@ impl Node for ast::located::ExprYield { } } // constructor +impl NamedNode for ast::located::ExprYieldFrom { + const NAME: &'static str = "YieldFrom"; +} impl Node for ast::located::ExprYieldFrom { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprYieldFrom { @@ -3872,6 +4019,9 @@ impl Node for ast::located::ExprYieldFrom { } } // constructor +impl NamedNode for ast::located::ExprCompare { + const NAME: &'static str = "Compare"; +} impl Node for ast::located::ExprCompare { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprCompare { @@ -3904,6 +4054,9 @@ impl Node for ast::located::ExprCompare { } } // constructor +impl NamedNode for ast::located::ExprCall { + const NAME: &'static str = "Call"; +} impl Node for ast::located::ExprCall { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprCall { @@ -3936,6 +4089,9 @@ impl Node for ast::located::ExprCall { } } // constructor +impl NamedNode for ast::located::ExprFormattedValue { + const NAME: &'static str = "FormattedValue"; +} impl Node for ast::located::ExprFormattedValue { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprFormattedValue { @@ -3975,6 +4131,9 @@ impl Node for ast::located::ExprFormattedValue { } } // constructor +impl NamedNode for ast::located::ExprJoinedStr { + const NAME: &'static str = "JoinedStr"; +} impl Node for ast::located::ExprJoinedStr { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprJoinedStr { @@ -4001,6 +4160,9 @@ impl Node for ast::located::ExprJoinedStr { } } // constructor +impl NamedNode for ast::located::ExprConstant { + const NAME: &'static str = "Constant"; +} impl Node for ast::located::ExprConstant { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprConstant { @@ -4029,6 +4191,9 @@ impl Node for ast::located::ExprConstant { } } // constructor +impl NamedNode for ast::located::ExprAttribute { + const NAME: &'static str = "Attribute"; +} impl Node for ast::located::ExprAttribute { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprAttribute { @@ -4061,6 +4226,9 @@ impl Node for ast::located::ExprAttribute { } } // constructor +impl NamedNode for ast::located::ExprSubscript { + const NAME: &'static str = "Subscript"; +} impl Node for ast::located::ExprSubscript { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprSubscript { @@ -4097,6 +4265,9 @@ impl Node for ast::located::ExprSubscript { } } // constructor +impl NamedNode for ast::located::ExprStarred { + const NAME: &'static str = "Starred"; +} impl Node for ast::located::ExprStarred { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprStarred { @@ -4123,6 +4294,9 @@ impl Node for ast::located::ExprStarred { } } // constructor +impl NamedNode for ast::located::ExprName { + const NAME: &'static str = "Name"; +} impl Node for ast::located::ExprName { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprName { @@ -4148,6 +4322,9 @@ impl Node for ast::located::ExprName { } } // constructor +impl NamedNode for ast::located::ExprList { + const NAME: &'static str = "List"; +} impl Node for ast::located::ExprList { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprList { @@ -4173,6 +4350,9 @@ impl Node for ast::located::ExprList { } } // constructor +impl NamedNode for ast::located::ExprTuple { + const NAME: &'static str = "Tuple"; +} impl Node for ast::located::ExprTuple { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprTuple { @@ -4198,6 +4378,9 @@ impl Node for ast::located::ExprTuple { } } // constructor +impl NamedNode for ast::located::ExprSlice { + const NAME: &'static str = "Slice"; +} impl Node for ast::located::ExprSlice { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExprSlice { @@ -4233,6 +4416,9 @@ impl Node for ast::located::ExprSlice { }) } } +impl NamedNode for ast::located::ExprContext { + const NAME: &'static str = "expr_context"; +} // sum impl Node for ast::located::ExprContext { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -4262,6 +4448,9 @@ impl Node for ast::located::ExprContext { }) } } +impl NamedNode for ast::located::Boolop { + const NAME: &'static str = "boolop"; +} // sum impl Node for ast::located::Boolop { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -4288,6 +4477,9 @@ impl Node for ast::located::Boolop { }) } } +impl NamedNode for ast::located::Operator { + const NAME: &'static str = "operator"; +} // sum impl Node for ast::located::Operator { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -4347,6 +4539,9 @@ impl Node for ast::located::Operator { }) } } +impl NamedNode for ast::located::Unaryop { + const NAME: &'static str = "unaryop"; +} // sum impl Node for ast::located::Unaryop { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -4379,6 +4574,9 @@ impl Node for ast::located::Unaryop { }) } } +impl NamedNode for ast::located::Cmpop { + const NAME: &'static str = "cmpop"; +} // sum impl Node for ast::located::Cmpop { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -4430,6 +4628,9 @@ impl Node for ast::located::Cmpop { } } // product +impl NamedNode for ast::located::Comprehension { + const NAME: &'static str = "comprehension"; +} impl Node for ast::located::Comprehension { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::Comprehension { @@ -4473,6 +4674,9 @@ impl Node for ast::located::Comprehension { }) } } +impl NamedNode for ast::located::Excepthandler { + const NAME: &'static str = "excepthandler"; +} // sum impl Node for ast::located::Excepthandler { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -4495,6 +4699,9 @@ impl Node for ast::located::Excepthandler { } } // constructor +impl NamedNode for ast::located::ExcepthandlerExceptHandler { + const NAME: &'static str = "ExceptHandler"; +} impl Node for ast::located::ExcepthandlerExceptHandler { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::ExcepthandlerExceptHandler { @@ -4534,9 +4741,12 @@ impl Node for ast::located::ExcepthandlerExceptHandler { } } // product -impl Node for ast::located::PythonArguments { +impl NamedNode for ast::located::Arguments { + const NAME: &'static str = "arguments"; +} +impl Node for ast::located::Arguments { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let ast::located::PythonArguments { + let ast::located::Arguments { posonlyargs, args, vararg, @@ -4566,7 +4776,7 @@ impl Node for ast::located::PythonArguments { node.into() } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { - Ok(ast::located::PythonArguments { + Ok(ast::located::Arguments { posonlyargs: Node::ast_from_object( _vm, get_node_field(_vm, &_object, "posonlyargs", "arguments")?, @@ -4595,6 +4805,9 @@ impl Node for ast::located::PythonArguments { } } // product +impl NamedNode for ast::located::Arg { + const NAME: &'static str = "arg"; +} impl Node for ast::located::Arg { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::Arg { @@ -4629,6 +4842,9 @@ impl Node for ast::located::Arg { } } // product +impl NamedNode for ast::located::Keyword { + const NAME: &'static str = "keyword"; +} impl Node for ast::located::Keyword { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::Keyword { @@ -4657,6 +4873,9 @@ impl Node for ast::located::Keyword { } } // product +impl NamedNode for ast::located::Alias { + const NAME: &'static str = "alias"; +} impl Node for ast::located::Alias { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::Alias { @@ -4685,6 +4904,9 @@ impl Node for ast::located::Alias { } } // product +impl NamedNode for ast::located::Withitem { + const NAME: &'static str = "withitem"; +} impl Node for ast::located::Withitem { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::Withitem { @@ -4716,6 +4938,9 @@ impl Node for ast::located::Withitem { } } // product +impl NamedNode for ast::located::MatchCase { + const NAME: &'static str = "match_case"; +} impl Node for ast::located::MatchCase { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::MatchCase { @@ -4749,6 +4974,9 @@ impl Node for ast::located::MatchCase { }) } } +impl NamedNode for ast::located::Pattern { + const NAME: &'static str = "pattern"; +} // sum impl Node for ast::located::Pattern { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -4806,6 +5034,9 @@ impl Node for ast::located::Pattern { } } // constructor +impl NamedNode for ast::located::PatternMatchValue { + const NAME: &'static str = "MatchValue"; +} impl Node for ast::located::PatternMatchValue { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::PatternMatchValue { @@ -4832,6 +5063,9 @@ impl Node for ast::located::PatternMatchValue { } } // constructor +impl NamedNode for ast::located::PatternMatchSingleton { + const NAME: &'static str = "MatchSingleton"; +} impl Node for ast::located::PatternMatchSingleton { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::PatternMatchSingleton { @@ -4858,6 +5092,9 @@ impl Node for ast::located::PatternMatchSingleton { } } // constructor +impl NamedNode for ast::located::PatternMatchSequence { + const NAME: &'static str = "MatchSequence"; +} impl Node for ast::located::PatternMatchSequence { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::PatternMatchSequence { @@ -4884,6 +5121,9 @@ impl Node for ast::located::PatternMatchSequence { } } // constructor +impl NamedNode for ast::located::PatternMatchMapping { + const NAME: &'static str = "MatchMapping"; +} impl Node for ast::located::PatternMatchMapping { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::PatternMatchMapping { @@ -4921,6 +5161,9 @@ impl Node for ast::located::PatternMatchMapping { } } // constructor +impl NamedNode for ast::located::PatternMatchClass { + const NAME: &'static str = "MatchClass"; +} impl Node for ast::located::PatternMatchClass { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::PatternMatchClass { @@ -4964,6 +5207,9 @@ impl Node for ast::located::PatternMatchClass { } } // constructor +impl NamedNode for ast::located::PatternMatchStar { + const NAME: &'static str = "MatchStar"; +} impl Node for ast::located::PatternMatchStar { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::PatternMatchStar { @@ -4988,6 +5234,9 @@ impl Node for ast::located::PatternMatchStar { } } // constructor +impl NamedNode for ast::located::PatternMatchAs { + const NAME: &'static str = "MatchAs"; +} impl Node for ast::located::PatternMatchAs { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::PatternMatchAs { @@ -5018,6 +5267,9 @@ impl Node for ast::located::PatternMatchAs { } } // constructor +impl NamedNode for ast::located::PatternMatchOr { + const NAME: &'static str = "MatchOr"; +} impl Node for ast::located::PatternMatchOr { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::PatternMatchOr { @@ -5043,6 +5295,9 @@ impl Node for ast::located::PatternMatchOr { }) } } +impl NamedNode for ast::located::TypeIgnore { + const NAME: &'static str = "type_ignore"; +} // sum impl Node for ast::located::TypeIgnore { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { @@ -5065,6 +5320,9 @@ impl Node for ast::located::TypeIgnore { } } // constructor +impl NamedNode for ast::located::TypeIgnoreTypeIgnore { + const NAME: &'static str = "TypeIgnore"; +} impl Node for ast::located::TypeIgnoreTypeIgnore { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::TypeIgnoreTypeIgnore { diff --git a/vm/src/stdlib/builtins.rs b/vm/src/stdlib/builtins.rs index 9b4a316b13..8de45bfd81 100644 --- a/vm/src/stdlib/builtins.rs +++ b/vm/src/stdlib/builtins.rs @@ -21,8 +21,7 @@ mod builtins { convert::ToPyException, function::{ ArgBytesLike, ArgCallable, ArgIndex, ArgIntoBool, ArgIterable, ArgMapping, - ArgStrOrBytesLike, Either, FsPath, FuncArgs, KwArgs, OptionalArg, OptionalOption, - PosArgs, + ArgStrOrBytesLike, Either, FuncArgs, KwArgs, OptionalArg, OptionalOption, PosArgs, }, protocol::{PyIter, PyIterReturn}, py_io, @@ -98,7 +97,7 @@ mod builtins { #[allow(dead_code)] struct CompileArgs { source: PyObjectRef, - filename: FsPath, + filename: PyStrRef, mode: PyStrRef, #[pyarg(any, optional)] flags: OptionalArg, diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index f6af1f9f94..29ee1dc21a 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -128,7 +128,6 @@ mod _io { }; use bstr::ByteSlice; use crossbeam_utils::atomic::AtomicCell; - use malachite_bigint::{BigInt, BigUint}; use num_traits::ToPrimitive; use std::{ io::{self, prelude::*, Cursor, SeekFrom}, @@ -2117,7 +2116,7 @@ mod _io { const NEED_EOF_OFF: usize = Self::CHARS_TO_SKIP_OFF + 4; const BYTES_TO_SKIP_OFF: usize = Self::NEED_EOF_OFF + 1; const BYTE_LEN: usize = Self::BYTES_TO_SKIP_OFF + 4; - fn parse(cookie: &BigInt) -> Option { + fn parse(cookie: &num_bigint::BigInt) -> Option { let (_, mut buf) = cookie.to_bytes_le(); if buf.len() > Self::BYTE_LEN { return None; @@ -2142,7 +2141,7 @@ mod _io { bytes_to_skip: get_field!(i32, BYTES_TO_SKIP_OFF), }) } - fn build(&self) -> BigInt { + fn build(&self) -> num_bigint::BigInt { let mut buf = [0; Self::BYTE_LEN]; macro_rules! set_field { ($field:expr, $off:ident) => {{ @@ -2157,7 +2156,7 @@ mod _io { set_field!(self.chars_to_skip, CHARS_TO_SKIP_OFF); set_field!(self.need_eof as u8, NEED_EOF_OFF); set_field!(self.bytes_to_skip, BYTES_TO_SKIP_OFF); - BigUint::from_bytes_le(&buf).into() + num_bigint::BigUint::from_bytes_le(&buf).into() } fn set_decoder_state(&self, decoder: &PyObject, vm: &VirtualMachine) -> PyResult<()> { if self.start_pos == 0 && self.dec_flags == 0 { diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index 91dbd7489d..cc5cd35df7 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -1092,54 +1092,7 @@ mod decl { } #[pyclass(with(IterNext, Iterable, Constructor))] - impl PyItertoolsAccumulate { - #[pymethod(magic)] - fn setstate(zelf: PyRef, state: PyObjectRef, _vm: &VirtualMachine) -> PyResult<()> { - *zelf.acc_value.write() = Some(state); - Ok(()) - } - - #[pymethod(magic)] - fn reduce(zelf: PyRef, vm: &VirtualMachine) -> PyTupleRef { - let class = zelf.class().to_owned(); - let binop = zelf.binop.clone(); - let it = zelf.iterable.clone(); - let acc_value = zelf.acc_value.read().clone(); - if let Some(initial) = &zelf.initial { - let chain_args = PyList::from(vec![initial.clone(), it.to_pyobject(vm)]); - let chain = PyItertoolsChain { - source: PyRwLock::new(Some(chain_args.to_pyobject(vm).get_iter(vm).unwrap())), - active: PyRwLock::new(None), - }; - let tup = vm.new_tuple((chain, binop)); - return vm.new_tuple((class, tup, acc_value)); - } - match acc_value { - Some(obj) if obj.is(&vm.ctx.none) => { - let chain_args = PyList::from(vec![]); - let chain = PyItertoolsChain { - source: PyRwLock::new(Some( - chain_args.to_pyobject(vm).get_iter(vm).unwrap(), - )), - active: PyRwLock::new(None), - } - .into_pyobject(vm); - let acc = Self { - iterable: PyIter::new(chain), - binop, - initial: None, - acc_value: PyRwLock::new(None), - }; - let tup = vm.new_tuple((acc, 1, None::)); - let islice_cls = PyItertoolsIslice::class(&vm.ctx).to_owned(); - return vm.new_tuple((islice_cls, tup)); - } - _ => {} - } - let tup = vm.new_tuple((it, binop)); - vm.new_tuple((class, tup, acc_value)) - } - } + impl PyItertoolsAccumulate {} impl SelfIter for PyItertoolsAccumulate {} impl IterNext for PyItertoolsAccumulate { diff --git a/vm/src/stdlib/marshal.rs b/vm/src/stdlib/marshal.rs index 35f9b93d5f..7c718f8679 100644 --- a/vm/src/stdlib/marshal.rs +++ b/vm/src/stdlib/marshal.rs @@ -15,7 +15,7 @@ mod decl { protocol::PyBuffer, PyObjectRef, PyResult, TryFromObject, VirtualMachine, }; - use malachite_bigint::BigInt; + use num_bigint::BigInt; use num_complex::Complex64; use num_traits::Zero; use rustpython_compiler_core::marshal; diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index d10acf1b26..9854bf59ed 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -5,7 +5,6 @@ use crate::{ function::{ArgumentError, FromArgs, FsPath, FuncArgs}, AsObject, Py, PyObjectRef, PyPayload, PyResult, TryFromObject, VirtualMachine, }; - use std::{ ffi, fs, io, path::{Path, PathBuf}, diff --git a/vm/src/stdlib/thread.rs b/vm/src/stdlib/thread.rs index 63e66474d1..c5b91871f5 100644 --- a/vm/src/stdlib/thread.rs +++ b/vm/src/stdlib/thread.rs @@ -233,8 +233,10 @@ pub(crate) mod _thread { } let new_mut = RawRMutex::INIT; - let old_mutex: AtomicCell<&RawRMutex> = AtomicCell::new(&self.mu); - old_mutex.swap(&new_mut); + unsafe { + let old_mutex: AtomicCell<&RawRMutex> = AtomicCell::new(&self.mu); + old_mutex.swap(&new_mut); + } Ok(()) } diff --git a/vm/src/vm/context.rs b/vm/src/vm/context.rs index 124fffdd4d..f9982c9e9a 100644 --- a/vm/src/vm/context.rs +++ b/vm/src/vm/context.rs @@ -25,7 +25,7 @@ use crate::{ types::{PyTypeFlags, PyTypeSlots, TypeZoo}, PyResult, VirtualMachine, }; -use malachite_bigint::BigInt; +use num_bigint::BigInt; use num_complex::Complex64; use num_traits::ToPrimitive; use rustpython_common::lock::PyRwLock; diff --git a/vm/src/vm/interpreter.rs b/vm/src/vm/interpreter.rs index a27c1f5dd8..aff8ef05ca 100644 --- a/vm/src/vm/interpreter.rs +++ b/vm/src/vm/interpreter.rs @@ -104,7 +104,7 @@ mod tests { builtins::{int, PyStr}, PyObjectRef, }; - use malachite_bigint::ToBigInt; + use num_bigint::ToBigInt; #[test] fn test_add_py_integers() { diff --git a/vm/src/vm/setting.rs b/vm/src/vm/setting.rs index 3b9c82cafc..6158a30a68 100644 --- a/vm/src/vm/setting.rs +++ b/vm/src/vm/setting.rs @@ -82,14 +82,6 @@ pub struct Settings { pub profile_format: Option, } -impl Settings { - pub fn with_path(path: String) -> Self { - let mut settings = Self::default(); - settings.path_list.push(path); - settings - } -} - /// Sensible default settings. impl Default for Settings { fn default() -> Self {